mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
328 lines
29 KiB
HTML
328 lines
29 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
|
<meta name="generator" content="Doxygen 1.8.17"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>rippled: Overlay</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr style="height: 56px;">
|
|
<td id="projectalign" style="padding-left: 0.5em;">
|
|
<div id="projectname">rippled
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.8.17 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */</script>
|
|
<div id="main-nav"></div>
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
</div><!-- top -->
|
|
<div class="PageDoc"><div class="header">
|
|
<div class="headertitle">
|
|
<div class="title">Overlay </div> </div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><h1><a class="anchor" id="autotoc_md217"></a>
|
|
Introduction</h1>
|
|
<p>The <em>XRP Ledger network</em> consists of a collection of <em>peers</em> running **<code>rippled</code>** or other compatible software. Each peer maintains multiple outgoing connections and optional incoming connections to other peers. These connections are made over both the public Internet and private local area networks. This network defines a connected directed graph of nodes where vertices are instances of <code>rippled</code> and edges are persistent TCP/IP connections. Peers send and receive messages to other connected peers. This peer to peer network, layered on top of the public and private Internet, forms an <a href="http://en.wikipedia.org/wiki/Overlay_network"><em>overlay network</em></a>. The contents of the messages and the behavior of peers in response to the messages, plus the information exchanged during the handshaking phase of connection establishment, defines the <em>XRP Ledger peer protocol</em> (or <em>protocol</em> in this context).</p>
|
|
<h1><a class="anchor" id="autotoc_md218"></a>
|
|
Overview</h1>
|
|
<p>Each connection is represented by a <em>Peer</em> object. The Overlay manager establishes, receives, and maintains connections to peers. Protocol messages are exchanged between peers and serialized using <a href="https://developers.google.com/protocol-buffers/"><em>Google Protocol Buffers</em></a>.</p>
|
|
<h2><a class="anchor" id="autotoc_md219"></a>
|
|
Structure</h2>
|
|
<p>Each connection between peers is identified by its connection type, which affects the behavior of message routing. At present, only a single connection type is supported: <b>Peer</b>.</p>
|
|
<h1><a class="anchor" id="autotoc_md220"></a>
|
|
Handshake</h1>
|
|
<p>To establish a protocol connection, a peer makes an outgoing TLS encrypted connection to a remote peer, then sends an HTTP request with no message body.</p>
|
|
<h2><a class="anchor" id="autotoc_md221"></a>
|
|
HTTP</h2>
|
|
<p>The HTTP <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html">request</a> must:</p>
|
|
<ul>
|
|
<li>Use HTTP version 1.1.</li>
|
|
<li>Specify a request URI consisting of a single forward slash character ("/") indicating the server root. Requests using different URIs are reserved for future protocol implementations.</li>
|
|
<li>Use the <a href="http://en.wikipedia.org/wiki/HTTP/1.1_Upgrade_header"><em>HTTP/1.1 Upgrade</em></a> mechanism with additional custom fields to communicate protocol specific information related to the upgrade.</li>
|
|
</ul>
|
|
<p>HTTP requests which do not conform to this requirements must generate an appropriate HTTP error and result in the connection being closed.</p>
|
|
<p>Upon receipt of a well-formed HTTP upgrade request, and validation of the protocol specific parameters, a peer will either send back a HTTP 101 response and switch to the requested protocol, or a message indicating that the request failed (e.g. by sending HTTP 400 "Bad Request" or HTTP 503 "Service Unavailable").</p>
|
|
<h4><a class="anchor" id="autotoc_md222"></a>
|
|
Example HTTP Upgrade Request</h4>
|
|
<div class="fragment"><div class="line">GET / HTTP/1.1</div>
|
|
<div class="line">User-Agent: rippled-1.4.0-b1+DEBUG</div>
|
|
<div class="line">Upgrade: RTXP/1.2, XRPL/2.0</div>
|
|
<div class="line">Connection: Upgrade</div>
|
|
<div class="line">Connect-As: Peer</div>
|
|
<div class="line">Crawl: public</div>
|
|
<div class="line">Network-ID: 1</div>
|
|
<div class="line">Network-Time: 619234489</div>
|
|
<div class="line">Public-Key: n94MvLTiHQJjByfGZzvQewTxQP2qjF6shQcuHwCjh5WoiozBrdpX</div>
|
|
<div class="line">Session-Signature: MEUCIQCOO8tHOh/tgCSRNe6WwOwmIF6urZ5uSB8l9aAf5q7iRAIgA4aONKBZhpP5RuOuhJP2dP+2UIRioEJcfU4/m4gZdYo=</div>
|
|
<div class="line">Remote-IP: 192.0.2.79</div>
|
|
<div class="line">Closed-Ledger: llRZSKqvNieGpPqbFGnm358pmF1aW96SDIUQcnMh6HI=</div>
|
|
<div class="line">Previous-Ledger: q4aKbP7sd5wv+EXArwCmQiWZhq9AwBl2p/hCtpGJNsc=</div>
|
|
</div><!-- fragment --><h4><a class="anchor" id="autotoc_md223"></a>
|
|
Example HTTP Upgrade Response (Success)</h4>
|
|
<div class="fragment"><div class="line">HTTP/1.1 101 Switching Protocols</div>
|
|
<div class="line">Connection: Upgrade</div>
|
|
<div class="line">Upgrade: RTXP/1.2</div>
|
|
<div class="line">Connect-As: Peer</div>
|
|
<div class="line">Server: rippled-1.3.1</div>
|
|
<div class="line">Crawl: public</div>
|
|
<div class="line">Public-Key: n9K1ZXXXzzA3dtgKBuQUnZXkhygMRgZbSo3diFNPVHLMsUG5osJM</div>
|
|
<div class="line">Session-Signature: MEQCIHMlLGTcGyPvHji7WY2nRM2B0iSBnw9xeDUGW7bPq7IjAiAmy+ofEu+8nOq2eChRTr3wjoKi3EYRqLgzP+q+ORFcig==</div>
|
|
<div class="line">Network-Time: 619234797</div>
|
|
<div class="line">Closed-Ledger: h7HL85W9ywkex+G7p42USVeV5kE04CWK+4DVI19Of8I=</div>
|
|
<div class="line">Previous-Ledger: EPvIpAD2iavGFyyZYi8REexAXyKGXsi1jMF7OIBY6/Y=</div>
|
|
</div><!-- fragment --><h4><a class="anchor" id="autotoc_md224"></a>
|
|
Example HTTP Upgrade Response (Failure: no slots available)</h4>
|
|
<div class="fragment"><div class="line">HTTP/1.1 503 Service Unavailable</div>
|
|
<div class="line">Server: rippled-0.27.0</div>
|
|
<div class="line">Remote-Address: 63.104.209.13</div>
|
|
<div class="line">Content-Length: 253</div>
|
|
<div class="line">Content-Type: application/json</div>
|
|
<div class="line">{"peer-ips":["54.68.219.39:51235","54.187.191.179:51235",</div>
|
|
<div class="line">"107.150.55.21:6561","54.186.230.77:51235","54.187.110.243:51235",</div>
|
|
<div class="line">"85.127.34.221:51235","50.43.33.236:51235","54.187.138.75:51235"]}</div>
|
|
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md225"></a>
|
|
Standard Fields</h3>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>User-Agent</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter"></td></tr>
|
|
</table>
|
|
<p>The <code>User-Agent</code> field indicates the version of the software that the peer that is making the HTTP request is using. No semantic meaning is assigned to the value in this field but it is recommended that implementations specify the version of the software that is used.</p>
|
|
<p>See <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43">RFC2616 §14.43</a>.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Server</code> </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The <code>Server</code> field indicates the version of the software that the peer that is processing the HTTP request is using. No semantic meaning is assigned to the value in this field but it is recommended that implementations specify the version of the software that is used.</p>
|
|
<p>See <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.38">RFC2616 §14.38</a>.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Connection</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The <code>Connection</code> field should have a value of <code>Upgrade</code> to indicate that a request to upgrade the connection is being performed.</p>
|
|
<p>See <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10">RFC2616 §14.10</a>.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Upgrade</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The <code>Upgrade</code> field is part of the standard connection upgrade mechanism and must be present in both requests and responses. It is used to negotiate the version of the protocol that will be used after the upgrade request completes.</p>
|
|
<p>For requests, it should consist of a comma delimited list of at least one element, where each element specifies a protocol version that the requesting server is willing to use.</p>
|
|
<p>For responses, it should a consist of <em>single element</em> matching one of the elements provided in the corresponding request. If the server does not understand any of the available protocol versions, the upgrade request should fail with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response).</p>
|
|
<p>Protocol versions are string of the form <code>XRPL/</code> followed by a dotted major and minor protocol version number, where the major number is greater than or equal to 2 and the minor is greater than or equal to 0.</p>
|
|
<p>See <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.42">RFC 2616 §14.42</a></p>
|
|
<h3><a class="anchor" id="autotoc_md226"></a>
|
|
Custom Fields</h3>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Connect-As</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The mandatory <code>Connect-As</code> field is used to specify that type of connection that is being requested.</p>
|
|
<p>For requests the value consists of a comma delimited list of elements, where each element describes a possible connection type. Only one connection types is supported at present: **<code>peer</code>**.</p>
|
|
<p>For responses, the value must consist of exactly one element from the list of elements specified in the request. If a server processing a request does not recognize any of the connection types, the request should fail with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response).</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Remote-IP</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Remote-IP</code> field contains the string representation of the IP address of the remote end of the connection as seen from the peer that is sending the field.</p>
|
|
<p>By observing values of this field from a sufficient number of different servers, a peer making outgoing connections can deduce its own IP address.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Local-IP</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Local-IP</code> field contains the string representation of the IP address that the peer sending the field believes to be its own.</p>
|
|
<p>Servers receiving this field can detect IP address mismatches, which may indicate a potential man-in-the-middle attack.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Network-ID</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Network-ID</code> can be used to identify to which of several <a href="https://xrpl.org/parallel-networks.html">parallel networks</a> the server sending the field is joined.</p>
|
|
<p>The value, if the field is present, is a 32-bit unsigned integer. The following well-known values are in use:</p>
|
|
<ul>
|
|
<li><b>0</b>: The "main net"</li>
|
|
<li><b>1</b>: The Ripple-operated <a href="https://xrpl.org/xrp-test-net-faucet.html">Test Net</a>.</li>
|
|
</ul>
|
|
<p>If a server configured to join one network receives a connection request from a server configured to join another network, the request should fail with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response).</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Network-Time</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Network-Time</code> field reports the current <a href="https://xrpl.org/basic-data-types.html#specifying-time">time</a> according to sender's internal clock.</p>
|
|
<p>Servers should fail a connection if their clocks are not within 20 seconds of each other with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response).</p>
|
|
<p>It is highly recommended that servers synchronize their clocks using time synchronization software. For more on this topic, please visit <a href="http://www.ntp.org/">ntp.org</a>.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Public-Key</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The mandatory <code>Public-Key</code> field identifies the sending server's public key, encoded in base58 using the standard encoding for node public keys.</p>
|
|
<p>See: <a href="https://xrpl.org/base58-encodings.html">https://xrpl.org/base58-encodings.html</a></p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Server-Domain</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Server-Domain</code> field allows a server to report the domain that it is operating under. The value is configured by the server administrator in the configuration file using the <code>[server_domain]</code> key.</p>
|
|
<p>The value is advisory and is not used by the code at this time, except for reporting purposes. External tools should verify this value prior to using it by attempting to locate a <a href="https://xrpl.org/xrp-ledger-toml.html">TOML file</a> under the specified domain and locating the public key of this server under the <code>[NODES]</code> key.</p>
|
|
<p>Sending a malformed domain will prevent a connection from being established.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Session-Signature</code> </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td><td class="markdownTableBodyCenter">:heavy_check_mark: </td></tr>
|
|
</table>
|
|
<p>The <code>Session-Signature</code> field is mandatory and is used to secure the peer link against certain types of attack. For more details see "Session Signature" below.</p>
|
|
<p>The value is presently encoded using <b>Base64</b> encoding, but implementations should support both <b>Base64</b> and <b>HEX</b> encoding for this value.</p>
|
|
<p>For more details on this field, please see <b>Session Signature</b> below.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Crawl</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>The optional <code>Crawl</code> field can be used by a server to indicate whether peers should include it in crawl reports.</p>
|
|
<p>The field can take two values:</p><ul>
|
|
<li>**<code>Public</code>**: The server's IP address and port should be included in crawl reports.</li>
|
|
<li>**<code>Private</code>**: The server's IP address and port should not be included in crawl reports. <em>This is the default, if the field is omitted.</em></li>
|
|
</ul>
|
|
<p>For more on the Peer Crawler, please visit <a href="https://xrpl.org/peer-crawler.html">https://xrpl.org/peer-crawler.html</a>.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Closed-Ledger</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>If present, identifies the hash of the last ledger that the sending server considers to be closed.</p>
|
|
<p>The value is encoded as <b>HEX</b>, but implementations should support both <b>Base64</b> and <b>HEX</b> encoding for this value for legacy purposes.</p>
|
|
<table class="markdownTable">
|
|
<tr class="markdownTableHead">
|
|
<th class="markdownTableHeadNone">Field Name </th><th class="markdownTableHeadCenter">Request </th><th class="markdownTableHeadCenter">Response </th></tr>
|
|
<tr class="markdownTableRowOdd">
|
|
<td class="markdownTableBodyNone"><code>Previous-Ledger</code> </td><td class="markdownTableBodyCenter">:white_check_mark: </td><td class="markdownTableBodyCenter">:white_check_mark: </td></tr>
|
|
</table>
|
|
<p>If present, identifies the hash of the parent ledger that the sending server considers to be closed.</p>
|
|
<p>The value is presently encoded using <b>Base64</b> encoding, but implementations should support both <b>Base64</b> and <b>HEX</b> encoding for this value.</p>
|
|
<h3><a class="anchor" id="autotoc_md227"></a>
|
|
Additional Headers</h3>
|
|
<p>An implementation or operator may specify additional, optional fields and values in both requests and responses.</p>
|
|
<p>Implementations should not reject requests because of the presence of fields that they do not understand.</p>
|
|
<h2><a class="anchor" id="autotoc_md228"></a>
|
|
Session Signature</h2>
|
|
<p>Even for SSL/TLS encrypted connections, it is possible for an attacker to mount relatively inexpensive MITM attacks that can be extremely hard to detect and may afford the attacker the ability to intelligently tamper with messages exchanged between the two endpoints.</p>
|
|
<p>This risk can be mitigated if at least one side has a certificate from a certificate authority trusted by the other endpoint, but having a certificate is not always possible (or even desirable) in a decentralized and permissionless network.</p>
|
|
<p>Ultimately, the goal is to ensure that two endpoints A and B know that they are talking directly to each other over a single end-to-end SSL/TLS session instead of two separate SSL/TLS sessions, with an attacker acting as a proxy.</p>
|
|
<p>The XRP Ledger protocol prevents this attack by leveraging the fact that the two servers each have a node identity, in the form of **<code>secp256k1</code>** keypairs, and use that to strongly bind the SSL/TLS session to the node identities of each of the two servers at the end of the SSL/TLS session.</p>
|
|
<p>To do this we "reach into" the SSL/TLS session, and extract the **<code>finished</code>** messages for the local and remote endpoints, and combine them to generate a unique "fingerprint". By design, this fingerprint should be the same for both SSL/TLS endpoints.</p>
|
|
<p>That fingerprint, which is never shared over the wire (since each endpoint will calculate it independently), is then signed by each server using its public **<code>secp256k1</code>** node identity and the signature is transferred over the SSL/TLS encrypted link during the protocol handshake phase.</p>
|
|
<p>Each side of the link will verify that the provided signature is from the claimed public key against the session's unique fingerprint. If this signature check fails then the link <b>MUST</b> be dropped.</p>
|
|
<p>If an attacker, Eve, establishes two separate SSL sessions with Alice and Bob, the fingerprints of the two sessions will be different, and Eve will not be able to sign the fingerprint of her session with Bob with Alice's private key, or the fingerprint of her session with Alice with Bob's private key, and so both A and B will know that an active MITM attack is in progress and will close their connections.</p>
|
|
<p>If Eve simply proxies the raw bytes, she will be unable to decrypt the data being transferred between A and B and will not be able to intelligently tamper with the message stream between Alice and Bob, although she may be still be able to inject delays or terminate the link.</p>
|
|
<h1><a class="anchor" id="autotoc_md229"></a>
|
|
Ripple Clustering</h1>
|
|
<p>A cluster consists of more than one Ripple server under common administration that share load information, distribute cryptography operations, and provide greater response consistency.</p>
|
|
<p>Cluster nodes are identified by their public node keys. Cluster nodes exchange information about endpoints that are imposing load upon them. Cluster nodes share information about their internal load status. Cluster nodes do not have to verify the cryptographic signatures on messages received from other cluster nodes.</p>
|
|
<h2><a class="anchor" id="autotoc_md230"></a>
|
|
Configuration</h2>
|
|
<p>A server's public key can be determined from the output of the <code>server_info</code> command. The key is in the <code>pubkey_node</code> value, and is a text string beginning with the letter <code>n</code>. The key is maintained across runs in a database.</p>
|
|
<p>Cluster members are configured in the <code>rippled.cfg</code> file under <code>[cluster_nodes]</code>. Each member should be configured on a line beginning with the node public key, followed optionally by a space and a friendly name.</p>
|
|
<p>Because cluster members can introduce other cluster members, it is not necessary to configure every cluster member on every other cluster member. If a hub and spoke system is used, it is sufficient to configure every cluster member on the hub(s) and only configure the hubs on the spokes. That is, each spoke does not need to be configured on every other spoke.</p>
|
|
<p>New spokes can be added as follows:</p>
|
|
<ul>
|
|
<li>In the new spoke's <code>[cluster_nodes]</code>, include each hub's public node key</li>
|
|
<li>Start the spoke server and determine its public node key</li>
|
|
<li>Configure each hub with the new spoke's public key</li>
|
|
<li>Restart each hub, one by one</li>
|
|
<li>Restart the spoke</li>
|
|
</ul>
|
|
<h2><a class="anchor" id="autotoc_md231"></a>
|
|
Transaction Behavior</h2>
|
|
<p>When a transaction is received from a cluster member, several normal checks are bypassed:</p>
|
|
<p>Signature checking is bypassed because we trust that a cluster member would not relay a transaction with an incorrect signature. Validators may wish to disable this feature, preferring the additional load to get the additional security of having validators check each transaction.</p>
|
|
<p>Local checks for transaction checking are also bypassed. For example, a server will not reject a transaction from a cluster peer because the fee does not meet its current relay fee. It is preferable to keep the cluster in agreement and permit confirmation from one cluster member to more reliably indicate the transaction's acceptance by the cluster.</p>
|
|
<h2><a class="anchor" id="autotoc_md232"></a>
|
|
Server Load Information</h2>
|
|
<p>Cluster members exchange information on their server's load level. The load level is essentially the amount by which the normal fee levels are multiplied to get the server's fee for relaying transactions.</p>
|
|
<p>A server's effective load level, and the one it uses to determine its relay fee, is the highest of its local load level, the network load level, and the cluster load level. The cluster load level is the median load level reported by a cluster member.</p>
|
|
<h2><a class="anchor" id="autotoc_md233"></a>
|
|
Gossip</h2>
|
|
<p>Gossip is the mechanism by which cluster members share information about endpoints (typically IPv4 addresses) that are imposing unusually high load on them. The endpoint load manager takes into account gossip to reduce the amount of load the endpoint is permitted to impose on the local server before it is warned, disconnected, or banned.</p>
|
|
<p>Suppose, for example, that an attacker controls a large number of IP addresses, and with these, he can send sufficient requests to overload a server. Without gossip, he could use these same addresses to overload all the servers in a cluster. With gossip, if he chooses to use the same IP address to impose load on more than one server, he will find that the amount of load he can impose before getting disconnected is much lower.</p>
|
|
<h2><a class="anchor" id="autotoc_md234"></a>
|
|
Monitoring</h2>
|
|
<p>The <code>peers</code> command will report on the status of the cluster. The <code>cluster</code> object will contain one entry for each member of the cluster (either configured or introduced by another cluster member). The <code>age</code> field is the number of seconds since the server was last heard from. If the server is reporting an elevated cluster fee, that will be reported as well.</p>
|
|
<p>In the <code>peers</code> object, cluster members will contain a <code>cluster</code> field set to <code>true</code>.</p>
|
|
<hr />
|
|
</div></div><!-- contents -->
|
|
</div><!-- PageDoc -->
|
|
<!-- start footer part -->
|
|
<hr class="footer"/><address class="footer"><small>
|
|
Generated by  <a href="http://www.doxygen.org/index.html">
|
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
|
</a> 1.8.17
|
|
</small></address>
|
|
</body>
|
|
</html>
|