diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/rfc.html | 1772 | ||||
| -rw-r--r-- | docs/rfc.txt | 267 |
2 files changed, 2039 insertions, 0 deletions
diff --git a/docs/rfc.html b/docs/rfc.html new file mode 100644 index 0000000..42c570a --- /dev/null +++ b/docs/rfc.html @@ -0,0 +1,1772 @@ +<!DOCTYPE html> +<html lang="en" class="Internet-Draft"> +<head> +<meta charset="utf-8"> +<meta content="Common,Latin" name="scripts"> +<meta content="initial-scale=1.0" name="viewport"> +<title>System of Lightweight Electronic Communication</title> +<meta content="bt" name="author"> +<meta content=" + This document describes working principles, features and network protocol of +SOLEC system. + " name="description"> +<meta content="xml2rfc 3.32.0" name="generator"> +<meta content="solec-draft" name="keyword"> +<meta content="SOLEC" name="ietf.draft"> +<!-- Generator version information: + xml2rfc 3.32.0 + Python 3.14.3 + ConfigArgParse 1.7.5 + google-i18n-address 3.1.1 + intervaltree 3.2.1 + Jinja2 3.1.6 + lxml 6.0.2 + platformdirs 4.5.1 + pycountry 26.2.16 + PyYAML 6.0.3 + requests 2.32.5 + wcwidth 0.6.0 +--> +<link href="rfc.xml" rel="alternate" type="application/rfc+xml"> +<link href="#copyright" rel="license"> +<style type="text/css">/* + + NOTE: Changes at the bottom of this file overrides some earlier settings. + + Once the style has stabilized and has been adopted as an official RFC style, + this can be consolidated so that style settings occur only in one place, but + for now the contents of this file consists first of the initial CSS work as + provided to the RFC Formatter (xml2rfc) work, followed by itemized and + commented changes found necessary during the development of the v3 + formatters. + +*/ + +/* fonts */ +@import url('https://static.ietf.org/fonts/noto-sans/import.css'); /* Sans-serif */ +@import url('https://static.ietf.org/fonts/noto-serif/import.css'); /* Serif (print) */ +@import url('https://static.ietf.org/fonts/roboto-mono/import.css'); /* Monospace */ + +:root { + --font-sans: 'Noto Sans', Arial, Helvetica, sans-serif; + --font-serif: 'Noto Serif', 'Times', 'Times New Roman', serif; + --font-mono: 'Roboto Mono', Courier, 'Courier New', monospace; +} + +@viewport { + zoom: 1.0; +} +@-ms-viewport { + width: extend-to-zoom; + zoom: 1.0; +} +/* general and mobile first */ +html { +} +body { + max-width: 90%; + margin: 1.5em auto; + color: #222; + background-color: #fff; + font-size: 14px; + font-family: var(--font-sans); + line-height: 1.6; + scroll-behavior: smooth; + overflow-wrap: break-word; +} +.ears { + display: none; +} + +/* headings */ +#title, h1, h2, h3, h4, h5, h6 { + margin: 1em 0 0.5em; + font-weight: bold; + line-height: 1.3; +} +#title { + clear: both; + border-bottom: 1px solid #ddd; + margin: 0 0 0.5em 0; + padding: 1em 0 0.5em; +} +.author { + padding-bottom: 4px; +} +h1 { + font-size: 26px; + margin: 1em 0; +} +h2 { + font-size: 22px; + margin-top: -20px; /* provide offset for in-page anchors */ + padding-top: 33px; +} +h3 { + font-size: 18px; + margin-top: -36px; /* provide offset for in-page anchors */ + padding-top: 42px; +} +h4 { + font-size: 16px; + margin-top: -36px; /* provide offset for in-page anchors */ + padding-top: 42px; +} +h5, h6 { + font-size: 14px; +} +#n-copyright-notice { + border-bottom: 1px solid #ddd; + padding-bottom: 1em; + margin-bottom: 1em; +} +/* general structure */ +p { + padding: 0; + margin: 0 0 1em 0; + text-align: left; +} +div, span { + position: relative; +} +div { + margin: 0; +} +.alignRight.art-text { + background-color: #f9f9f9; + border: 1px solid #eee; + border-radius: 3px; + padding: 1em 1em 0; + margin-bottom: 1.5em; +} +.alignRight.art-text pre { + padding: 0; +} +.alignRight { + margin: 1em 0; +} +.alignRight > *:first-child { + border: none; + margin: 0; + float: right; + clear: both; +} +.alignRight > *:nth-child(2) { + clear: both; + display: block; + border: none; +} +svg { + display: block; +} +@media print { + svg { + max-height: 850px; + max-width: 660px; + } +} +svg[font-family~="serif" i], svg [font-family~="serif" i] { + font-family: var(--font-serif); +} +svg[font-family~="sans-serif" i], svg [font-family~="sans-serif" i] { + font-family: var(--font-sans); +} +svg[font-family~="monospace" i], svg [font-family~="monospace" i] { + font-family: var(--font-mono); +} +.alignCenter.art-text { + background-color: #f9f9f9; + border: 1px solid #eee; + border-radius: 3px; + padding: 1em 1em 0; + margin-bottom: 1.5em; +} +.alignCenter.art-text pre { + padding: 0; +} +.alignCenter { + margin: 1em 0; +} +.alignCenter > *:first-child { + display: table; + border: none; + margin: 0 auto; +} + +/* lists */ +ol, ul { + padding: 0; + margin: 0 0 1em 2em; +} +ol ol, ul ul, ol ul, ul ol { + margin-left: 1em; +} +li { + margin: 0 0 0.25em 0; +} +.ulCompact li { + margin: 0; +} +ul.empty, .ulEmpty { + list-style-type: none; +} +ul.empty li, .ulEmpty li { + margin-top: 0.5em; +} +ul.ulBare, li.ulBare { + margin-left: 0em !important; +} +ul.compact, .ulCompact, +ol.compact, .olCompact { + line-height: 100%; + margin: 0 0 0 2em; +} + +/* definition lists */ +dl { +} +dl > dt { + float: left; + margin-right: 1em; +} +/* +dl.nohang > dt { + float: none; +} +*/ +dl > dd { + margin-bottom: .8em; + min-height: 1.3em; +} +dl.compact > dd, .dlCompact > dd { + margin-bottom: 0em; +} +dl > dd > dl { + margin-top: 0.5em; + margin-bottom: 0em; +} + +/* links */ +a { + text-decoration: none; +} +a[href] { + color: #22e; /* Arlen: WCAG 2019 */ +} +a[href]:hover { + background-color: #f2f2f2; +} +figcaption a[href], +a[href].selfRef { + color: #222; +} +/* XXX probably not this: +a.selfRef:hover { + background-color: transparent; + cursor: default; +} */ + +/* Figures */ +tt, code, pre { + background-color: #f9f9f9; + font-family: var(--font-mono); +} +pre { + border: 1px solid #eee; + margin: 0; + padding: 1em; +} +img { + max-width: 100%; +} +figure { + margin: 0; +} +figure blockquote { + margin: 0.8em 0.4em 0.4em; +} +figcaption { + font-style: italic; + margin: 0 0 1em 0; +} +@media screen { + pre { + overflow-x: auto; + max-width: 100%; + max-width: calc(100% - 22px); + } +} + +/* aside, blockquote */ +aside, blockquote { + margin-left: 0; + padding: 1.2em 2em; +} +blockquote { + background-color: #f9f9f9; + color: #111; /* Arlen: WCAG 2019 */ + border: 1px solid #ddd; + border-radius: 3px; + margin: 1em 0; +} +blockquote > *:last-child { + margin-bottom: 0; +} +cite { + display: block; + text-align: right; + font-style: italic; +} +.xref { + overflow-wrap: normal; +} + +/* tables */ +table { + width: 100%; + margin: 0 0 1em; + border-collapse: collapse; + border: 1px solid #eee; +} +th, td { + text-align: left; + vertical-align: top; + padding: 0.5em 0.75em; +} +th { + text-align: left; + background-color: #e9e9e9; +} +tr:nth-child(2n+1) > td { + background-color: #f5f5f5; +} +table caption { + font-style: italic; + margin: 0; + padding: 0; + text-align: left; +} +table p { + /* XXX to avoid bottom margin on table row signifiers. If paragraphs should + be allowed within tables more generally, it would be far better to select on a class. */ + margin: 0; +} + +/* pilcrow */ +a.pilcrow { + color: #666; /* Arlen: AHDJ 2019 */ + text-decoration: none; + visibility: hidden; + user-select: none; + -ms-user-select: none; + -o-user-select:none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -webkit-touch-callout: none; +} +@media screen { + aside:hover > a.pilcrow, + p:hover > a.pilcrow, + blockquote:hover > a.pilcrow, + div:hover > a.pilcrow, + li:hover > a.pilcrow, + pre:hover > a.pilcrow { + visibility: visible; + } + a.pilcrow:hover { + background-color: transparent; + } +} + +/* misc */ +hr { + border: 0; + border-top: 1px solid #eee; +} +.bcp14 { + font-variant: small-caps; +} + +.role { + font-variant: all-small-caps; +} + +/* info block */ +#identifiers { + margin: 0; + font-size: 0.9em; +} +#identifiers dt { + width: 3em; + clear: left; +} +#identifiers dd { + float: left; + margin-bottom: 0; +} +/* Fix PDF info block run off issue */ +@media print { + #identifiers dd { + max-width: 100%; + } +} +#identifiers .authors .author { + display: inline-block; + margin-right: 1.5em; +} +#identifiers .authors .org { + font-style: italic; +} + +/* The prepared/rendered info at the very bottom of the page */ +.docInfo { + color: #666; /* Arlen: WCAG 2019 */ + font-size: 0.9em; + font-style: italic; + margin-top: 2em; +} +.docInfo .prepared { + float: left; +} +.docInfo .prepared { + float: right; +} + +/* table of contents */ +#toc { + padding: 0.75em 0 2em 0; + margin-bottom: 1em; +} +nav.toc ul { + margin: 0 0.5em 0 0; + padding: 0; + list-style: none; +} +nav.toc li { + line-height: 1.3em; + margin: 0.75em 0; + padding-left: 1.2em; + text-indent: -1.2em; +} +/* references */ +.references dt { + text-align: right; + font-weight: bold; + min-width: 7em; +} +.references dd { + margin-left: 8em; + overflow: auto; +} + +.refInstance { + margin-bottom: 1.25em; +} + +.refSubseries { + margin-bottom: 1.25em; +} + +.references .ascii { + margin-bottom: 0.25em; +} + +/* index */ +.index ul { + margin: 0 0 0 1em; + padding: 0; + list-style: none; +} +.index ul ul { + margin: 0; +} +.index li { + margin: 0; + text-indent: -2em; + padding-left: 2em; + padding-bottom: 5px; +} +.indexIndex { + margin: 0.5em 0 1em; +} +.index a { + font-weight: 700; +} +/* make the index two-column on all but the smallest screens */ +@media (min-width: 600px) { + .index ul { + -moz-column-count: 2; + -moz-column-gap: 20px; + } + .index ul ul { + -moz-column-count: 1; + -moz-column-gap: 0; + } +} + +/* authors */ +address.vcard { + font-style: normal; + margin: 1em 0; +} + +address.vcard .nameRole { + font-weight: 700; + margin-left: 0; +} +address.vcard .label { + font-family: var(--font-sans); + margin: 0.5em 0; +} +address.vcard .type { + display: none; +} +.alternative-contact { + margin: 1.5em 0 1em; +} +hr.addr { + border-top: 1px dashed; + margin: 0; + color: #ddd; + max-width: calc(100% - 16px); +} + +/* temporary notes */ +.rfcEditorRemove::before { + position: absolute; + top: 0.2em; + right: 0.2em; + padding: 0.2em; + content: "The RFC Editor will remove this note"; + color: #9e2a00; /* Arlen: WCAG 2019 */ + background-color: #ffd; /* Arlen: WCAG 2019 */ +} +.rfcEditorRemove { + position: relative; + padding-top: 1.8em; + background-color: #ffd; /* Arlen: WCAG 2019 */ + border-radius: 3px; +} +.cref { + background-color: #ffd; /* Arlen: WCAG 2019 */ + padding: 2px 4px; +} +.crefSource { + font-style: italic; +} +/* alternative layout for smaller screens */ +@media screen and (max-width: 1023px) { + body { + padding-top: 2em; + } + #title { + padding: 1em 0; + } + h1 { + font-size: 24px; + } + h2 { + font-size: 20px; + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 38px; + } + #identifiers dd { + max-width: 60%; + } + #toc { + position: fixed; + z-index: 2; + top: 0; + right: 0; + padding: 0; + margin: 0; + background-color: inherit; + border-bottom: 1px solid #ccc; + } + #toc h2 { + margin: -1px 0 0 0; + padding: 4px 0 4px 6px; + padding-right: 1em; + min-width: 190px; + font-size: 1.1em; + text-align: right; + background-color: #444; + color: white; + cursor: pointer; + } + #toc h2::before { /* css hamburger */ + float: right; + position: relative; + width: 1em; + height: 1px; + left: -164px; + margin: 6px 0 0 0; + background: white none repeat scroll 0 0; + box-shadow: 0 4px 0 0 white, 0 8px 0 0 white; + content: ""; + } + #toc nav { + display: none; + padding: 0.5em 1em 1em; + overflow: auto; + height: calc(100vh - 48px); + border-left: 1px solid #ddd; + } +} + +/* alternative layout for wide screens */ +@media screen and (min-width: 1024px) { + body { + max-width: 724px; + margin: 42px auto; + padding-left: 1.5em; + padding-right: 29em; + } + #toc { + position: fixed; + top: 42px; + right: 42px; + width: 25%; + margin: 0; + padding: 0 1em; + z-index: 1; + } + #toc h2 { + border-top: none; + border-bottom: 1px solid #ddd; + font-size: 1em; + font-weight: normal; + margin: 0; + padding: 0.25em 1em 1em 0; + } + #toc nav { + display: block; + height: calc(90vh - 84px); + bottom: 0; + padding: 0.5em 0 0; + overflow: auto; + } + img { /* future proofing */ + max-width: 100%; + height: auto; + } +} + +/* pagination */ +@media print { + body { + width: 100%; + } + p { + orphans: 3; + widows: 3; + } + #n-copyright-notice { + border-bottom: none; + } + #toc, #n-introduction { + page-break-before: always; + } + #toc { + border-top: none; + padding-top: 0; + } + figure, pre { + page-break-inside: avoid; + } + figure { + overflow: scroll; + } + .breakable pre { + break-inside: auto; + } + h1, h2, h3, h4, h5, h6 { + page-break-after: avoid; + } + h2+*, h3+*, h4+*, h5+*, h6+* { + page-break-before: avoid; + } + pre { + white-space: pre-wrap; + word-wrap: break-word; + font-size: 10pt; + } + table { + border: 1px solid #ddd; + } + td { + border-top: 1px solid #ddd; + } +} + +/* This is commented out here, as the string-set: doesn't + pass W3C validation currently */ +/* +.ears thead .left { + string-set: ears-top-left content(); +} + +.ears thead .center { + string-set: ears-top-center content(); +} + +.ears thead .right { + string-set: ears-top-right content(); +} + +.ears tfoot .left { + string-set: ears-bottom-left content(); +} + +.ears tfoot .center { + string-set: ears-bottom-center content(); +} + +.ears tfoot .right { + string-set: ears-bottom-right content(); +} +*/ + +@page :first { + padding-top: 0; + @top-left { + content: normal; + border: none; + } + @top-center { + content: normal; + border: none; + } + @top-right { + content: normal; + border: none; + } +} + +@page { + size: A4; + margin-bottom: 45mm; + padding-top: 20px; + /* The following is commented out here, but set appropriately by in code, as + the content depends on the document */ + /* + @top-left { + content: 'Internet-Draft'; + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-left { + content: string(ears-top-left); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-center { + content: string(ears-top-center); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-right { + content: string(ears-top-right); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @bottom-left { + content: string(ears-bottom-left); + vertical-align: top; + border-top: solid 1px #ccc; + } + @bottom-center { + content: string(ears-bottom-center); + vertical-align: top; + border-top: solid 1px #ccc; + } + @bottom-right { + content: '[Page ' counter(page) ']'; + vertical-align: top; + border-top: solid 1px #ccc; + } + */ + +} + +/* Changes introduced to fix issues found during implementation */ +/* Make sure links are clickable even if overlapped by following H* */ +a { + z-index: 2; +} +/* Separate body from document info even without intervening H1 */ +section { + clear: both; +} + + +/* Top align author divs, to avoid names without organization dropping level with org names */ +.author { + vertical-align: top; +} + +/* Leave room in document info to show Internet-Draft on one line */ +#identifiers dt { + width: 8em; +} + +/* Don't waste quite as much whitespace between label and value in doc info */ +#identifiers dd { + margin-left: 1em; +} + +/* Give floating toc a background color (needed when it's a div inside section */ +#toc { + background-color: white; +} + +/* Make the collapsed ToC header render white on gray also when it's a link */ +@media screen and (max-width: 1023px) { + #toc h2 a, + #toc h2 a:link, + #toc h2 a:focus, + #toc h2 a:hover, + #toc a.toplink, + #toc a.toplink:hover { + color: white; + background-color: #444; + text-decoration: none; + } +} + +/* Give the bottom of the ToC some whitespace */ +@media screen and (min-width: 1024px) { + #toc { + padding: 0 0 1em 1em; + } +} + +/* Style section numbers with more space between number and title */ +.section-number { + padding-right: 0.5em; +} + +/* prevent monospace from becoming overly large */ +tt, code, pre { + font-size: 95%; +} + +/* Fix the height/width aspect for ascii art*/ +.sourcecode pre, +.art-text pre { + line-height: 1.12; +} + + +/* Add styling for a link in the ToC that points to the top of the document */ +a.toplink { + float: right; + margin-right: 0.5em; +} + +/* Fix the dl styling to match the RFC 7992 attributes */ +dl > dt, +dl.dlParallel > dt { + float: left; + margin-right: 1em; +} +dl.dlNewline > dt { + float: none; +} + +/* Provide styling for table cell text alignment */ +table td.text-left, +table th.text-left { + text-align: left; +} +table td.text-center, +table th.text-center { + text-align: center; +} +table td.text-right, +table th.text-right { + text-align: right; +} + +/* Make the alternative author contact information look less like just another + author, and group it closer with the primary author contact information */ +.alternative-contact { + margin: 0.5em 0 0.25em 0; +} +address .non-ascii { + margin: 0 0 0 2em; +} + +/* With it being possible to set tables with alignment + left, center, and right, { width: 100%; } does not make sense */ +table { + width: auto; +} + +/* Avoid reference text that sits in a block with very wide left margin, + because of a long floating dt label.*/ +.references dd { + overflow: visible; +} + +/* Control caption placement */ +caption { + caption-side: bottom; +} + +/* Limit the width of the author address vcard, so names in right-to-left + script don't end up on the other side of the page. */ + +address.vcard { + max-width: 30em; + margin-right: auto; +} + +/* For address alignment dependent on LTR or RTL scripts */ +address div.left { + text-align: left; +} +address div.right { + text-align: right; +} + +/* Provide table alignment support. We can't use the alignX classes above + since they do unwanted things with caption and other styling. */ +table.right { + margin-left: auto; + margin-right: 0; +} +table.center { + margin-left: auto; + margin-right: auto; +} +table.left { + margin-left: 0; + margin-right: auto; +} + +/* Give the table caption label the same styling as the figcaption */ +caption a[href] { + color: #222; +} + +@media print { + .toplink { + display: none; + } + + /* avoid overwriting the top border line with the ToC header */ + #toc { + padding-top: 1px; + } + + /* Avoid page breaks inside dl and author address entries */ + .vcard { + page-break-inside: avoid; + } + +} +/* Tweak the bcp14 keyword presentation */ +.bcp14 { + font-variant: small-caps; + font-weight: bold; + font-size: 0.9em; +} +/* Tweak the invisible space above H* in order not to overlay links in text above */ + h2 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 31px; + } + h3 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 24px; + } + h4 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 24px; + } +/* Float artwork pilcrow to the right */ +@media screen { + .artwork a.pilcrow { + display: block; + line-height: 0.7; + margin-top: 0.15em; + } +} +/* Make pilcrows on dd visible */ +@media screen { + dd:hover > a.pilcrow { + visibility: visible; + } +} +/* Make the placement of figcaption match that of a table's caption + by removing the figure's added bottom margin */ +.alignLeft.art-text, +.alignCenter.art-text, +.alignRight.art-text { + margin-bottom: 0; +} +.alignLeft, +.alignCenter, +.alignRight { + margin: 1em 0 0 0; +} +/* In print, the pilcrow won't show on hover, so prevent it from taking up space, + possibly even requiring a new line */ +@media print { + a.pilcrow { + display: none; + } +} +/* Styling for the external metadata */ +div#external-metadata { + background-color: #eee; + padding: 0.5em; + margin-bottom: 0.5em; + display: none; +} +div#internal-metadata { + padding: 0.5em; /* to match the external-metadata padding */ +} +/* Styling for title RFC Number */ +h1#rfcnum { + clear: both; + margin: 0 0 -1em; + padding: 1em 0 0 0; +} +/* Make .olPercent look the same as <ol><li> */ +dl.olPercent > dd { + margin-bottom: 0.25em; + min-height: initial; +} +/* Give aside some styling to set it apart */ +aside { + border-left: 1px solid #ddd; + margin: 1em 0 1em 2em; + padding: 0.2em 2em; +} +aside > dl, +aside > ol, +aside > ul, +aside > table, +aside > p { + margin-bottom: 0.5em; +} +/* Additional page break settings */ +@media print { + figcaption, table caption { + page-break-before: avoid; + } +} +/* Font size adjustments for print */ +@media print { + body { font-size: 10pt; line-height: normal; max-width: 96%; } + h1 { font-size: 1.72em; padding-top: 1.5em; } /* 1*1.2*1.2*1.2 */ + h2 { font-size: 1.44em; padding-top: 1.5em; } /* 1*1.2*1.2 */ + h3 { font-size: 1.2em; padding-top: 1.5em; } /* 1*1.2 */ + h4 { font-size: 1em; padding-top: 1.5em; } + h5, h6 { font-size: 1em; margin: initial; padding: 0.5em 0 0.3em; } +} +/* Sourcecode margin in print, when there's no pilcrow */ +@media print { + .artwork, + .artwork > pre, + .sourcecode { + margin-bottom: 1em; + } +} +/* Avoid narrow tables forcing too narrow table captions, which may render badly */ +table { + min-width: 20em; +} +/* ol type a */ +ol.type-a { list-style-type: lower-alpha; } +ol.type-A { list-style-type: upper-alpha; } +ol.type-i { list-style-type: lower-roman; } +ol.type-I { list-style-type: upper-roman; } +/* Apply the print table and row borders in general, on request from the RPC, +and increase the contrast between border and odd row background slightly */ +table { + border: 1px solid #ddd; +} +td { + border-top: 1px solid #ddd; +} +tr { + break-inside: avoid; +} +tr:nth-child(2n+1) > td { + background-color: #f8f8f8; +} +/* Use style rules to govern display of the TOC. */ +@media screen and (max-width: 1023px) { + #toc nav { display: none; } + #toc.active nav { display: block; } +} +/* Add support for keepWithNext */ +.keepWithNext { + break-after: avoid-page; + break-after: avoid-page; +} +/* Add support for keepWithPrevious */ +.keepWithPrevious { + break-before: avoid-page; +} +/* Change the approach to avoiding breaks inside artwork etc. */ +figure, pre, table, .artwork, .sourcecode { + break-before: auto; + break-after: auto; +} +/* Avoid breaks between <dt> and <dd> */ +dl { + break-before: auto; + break-inside: auto; +} +dt { + break-before: auto; + break-after: avoid-page; +} +dd { + break-before: avoid-page; + break-after: auto; + orphans: 3; + widows: 3 +} +span.break, dd.break { + margin-bottom: 0; + min-height: 0; + break-before: auto; + break-inside: auto; + break-after: auto; +} +/* Undo break-before ToC */ +@media print { + #toc { + break-before: auto; + } +} +/* Text in compact lists should not get extra bottom margin space, + since that would makes the list not compact */ +ul.compact p, .ulCompact p, +ol.compact p, .olCompact p { + margin: 0; +} +/* But the list as a whole needs the extra space at the end */ +section ul.compact, +section .ulCompact, +section ol.compact, +section .olCompact { + margin-bottom: 1em; /* same as p not within ul.compact etc. */ +} +/* The tt and code background above interferes with for instance table cell + backgrounds. Changed to something a bit more selective. */ +tt, code { + background-color: transparent; +} +p tt, p code, li tt, li code, dt tt, dt code { + background-color: #f8f8f8; +} +/* Tweak the pre margin -- 0px doesn't come out well */ +pre { + margin-top: 0.5px; +} +/* Tweak the compact list text */ +ul.compact, .ulCompact, +ol.compact, .olCompact, +dl.compact, .dlCompact { + line-height: normal; +} +/* Don't add top margin for nested lists */ +li > ul, li > ol, li > dl, +dd > ul, dd > ol, dd > dl, +dl > dd > dl { + margin-top: initial; +} +/* Elements that should not be rendered on the same line as a <dt> */ +/* This should match the element list in writer.text.TextWriter.render_dl() */ +dd > div.artwork:first-child, +dd > aside:first-child, +dd > blockquote:first-child, +dd > figure:first-child, +dd > ol:first-child, +dd > div.sourcecode:first-child, +dd > table:first-child, +dd > ul:first-child { + clear: left; +} +/* fix for weird browser behaviour when <dd/> is empty */ +dt+dd:empty::before{ + content: "\00a0"; +} +/* Make paragraph spacing inside <li> smaller than in body text, to fit better within the list */ +li > p { + margin-bottom: 0.5em +} +/* Don't let p margin spill out from inside list items */ +li > p:last-of-type:only-child { + margin-bottom: 0; +} +</style> +<link href="rfc-local.css" rel="stylesheet" type="text/css"> +<script type="application/javascript">async function addMetadata(){try{const e=document.styleSheets[0].cssRules;for(let t=0;t<e.length;t++)if(/#identifiers/.exec(e[t].selectorText)){const a=e[t].cssText.replace("#identifiers","#external-updates");document.styleSheets[0].insertRule(a,document.styleSheets[0].cssRules.length)}}catch(e){console.log(e)}const e=document.getElementById("external-metadata");if(e)try{var t,a="",o=function(e){const t=document.getElementsByTagName("meta");for(let a=0;a<t.length;a++)if(t[a].getAttribute("name")===e)return t[a].getAttribute("content");return""}("rfc.number");if(o){t="https://www.rfc-editor.org/rfc/rfc"+o+".json";try{const e=await fetch(t);a=await e.json()}catch(e){t=document.URL.indexOf("html")>=0?document.URL.replace(/html$/,"json"):document.URL+".json";const o=await fetch(t);a=await o.json()}}if(!a)return;e.style.display="block";const s="",d="https://datatracker.ietf.org/doc",n="https://datatracker.ietf.org/ipr/search",c="https://www.rfc-editor.org/info",l=a.doc_id.toLowerCase(),i=a.doc_id.slice(0,3).toLowerCase(),f=a.doc_id.slice(3).replace(/^0+/,""),u={status:"Status",obsoletes:"Obsoletes",obsoleted_by:"Obsoleted By",updates:"Updates",updated_by:"Updated By",see_also:"See Also",errata_url:"Errata"};let h="<dl style='overflow:hidden' id='external-updates'>";["status","obsoletes","obsoleted_by","updates","updated_by","see_also","errata_url"].forEach(e=>{if("status"==e){a[e]=a[e].toLowerCase();var t=a[e].split(" "),o=t.length,w="",p=1;for(let e=0;e<o;e++)p<o?w=w+r(t[e])+" ":w+=r(t[e]),p++;a[e]=w}else if("obsoletes"==e||"obsoleted_by"==e||"updates"==e||"updated_by"==e){var g,m="",b=1;g=a[e].length;for(let t=0;t<g;t++)a[e][t]&&(a[e][t]=String(a[e][t]).toLowerCase(),m=b<g?m+"<a href='"+s+"/rfc/".concat(a[e][t])+"'>"+a[e][t].slice(3)+"</a>, ":m+"<a href='"+s+"/rfc/".concat(a[e][t])+"'>"+a[e][t].slice(3)+"</a>",b++);a[e]=m}else if("see_also"==e){var y,L="",C=1;y=a[e].length;for(let t=0;t<y;t++)if(a[e][t]){a[e][t]=String(a[e][t]);var _=a[e][t].slice(0,3),v=a[e][t].slice(3).replace(/^0+/,"");L=C<y?"RFC"!=_?L+"<a href='"+s+"/info/"+_.toLowerCase().concat(v.toLowerCase())+"'>"+_+" "+v+"</a>, ":L+"<a href='"+s+"/info/"+_.toLowerCase().concat(v.toLowerCase())+"'>"+v+"</a>, ":"RFC"!=_?L+"<a href='"+s+"/info/"+_.toLowerCase().concat(v.toLowerCase())+"'>"+_+" "+v+"</a>":L+"<a href='"+s+"/info/"+_.toLowerCase().concat(v.toLowerCase())+"'>"+v+"</a>",C++}a[e]=L}else if("errata_url"==e){var R="";R=a[e]?R+"<a href='"+a[e]+"'>Errata exist</a> | <a href='"+d+"/"+l+"'>Datatracker</a>| <a href='"+n+"/?"+i+"="+f+"&submit="+i+"'>IPR</a> | <a href='"+c+"/"+l+"'>Info page</a>":"<a href='"+d+"/"+l+"'>Datatracker</a> | <a href='"+n+"/?"+i+"="+f+"&submit="+i+"'>IPR</a> | <a href='"+c+"/"+l+"'>Info page</a>",a[e]=R}""!=a[e]?"Errata"==u[e]?h+=`<dt>More info:</dt><dd>${a[e]}</dd>`:h+=`<dt>${u[e]}:</dt><dd>${a[e]}</dd>`:"Errata"==u[e]&&(h+=`<dt>More info:</dt><dd>${a[e]}</dd>`)}),h+="</dl>",e.innerHTML=h}catch(e){console.log(e)}else console.log("Could not locate metadata <div> element");function r(e){return e.charAt(0).toUpperCase()+e.slice(1)}}window.removeEventListener("load",addMetadata),window.addEventListener("load",addMetadata);</script> +</head> +<body class="xml2rfc"> +<table class="ears"> +<thead><tr> +<td class="left">Internet-Draft</td> +<td class="center">SOLEC</td> +<td class="right">March 2026</td> +</tr></thead> +<tfoot><tr> +<td class="left">bt</td> +<td class="center">Expires 30 September 2026</td> +<td class="right">[Page]</td> +</tr></tfoot> +</table> +<div id="external-metadata" class="document-information"></div> +<div id="internal-metadata" class="document-information"> +<dl id="identifiers"> +<dt class="label-workgroup">Workgroup:</dt> +<dd class="workgroup">SOLEC Working Group</dd> +<dt class="label-internet-draft">Internet-Draft:</dt> +<dd class="internet-draft">SOLEC</dd> +<dt class="label-published">Published:</dt> +<dd class="published"> +<time datetime="2026-03-29" class="published">29 March 2026</time> + </dd> +<dt class="label-intended-status">Intended Status:</dt> +<dd class="intended-status">Experimental</dd> +<dt class="label-expires">Expires:</dt> +<dd class="expires"><time datetime="2026-09-30">30 September 2026</time></dd> +<dt class="label-authors">Author:</dt> +<dd class="authors"> +<div class="author"> + <div class="author-name">bt, <span class="editor">Ed.</span> +</div> +<div class="org">RCTT.net</div> +</div> +</dd> +</dl> +</div> +<h1 id="title">System of Lightweight Electronic Communication</h1> +<section id="section-abstract"> + <h2 id="abstract"><a href="#abstract" class="selfRef">Abstract</a></h2> +<p id="section-abstract-1">This document describes working principles, features and network protocol of +SOLEC system.<a href="#section-abstract-1" class="pilcrow">¶</a></p> +</section> +<div id="status-of-memo"> +<section id="section-boilerplate.1"> + <h2 id="name-status-of-this-memo"> +<a href="#name-status-of-this-memo" class="section-name selfRef">Status of This Memo</a> + </h2> +<p id="section-boilerplate.1-1"> + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.<a href="#section-boilerplate.1-1" class="pilcrow">¶</a></p> +<p id="section-boilerplate.1-2"> + Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at <span><a href="https://datatracker.ietf.org/drafts/current/">https://datatracker.ietf.org/drafts/current/</a></span>.<a href="#section-boilerplate.1-2" class="pilcrow">¶</a></p> +<p id="section-boilerplate.1-3"> + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p> +<p id="section-boilerplate.1-4"> + This Internet-Draft will expire on 30 September 2026.<a href="#section-boilerplate.1-4" class="pilcrow">¶</a></p> +</section> +</div> +<div id="copyright"> +<section id="section-boilerplate.2"> + <h2 id="name-copyright-notice"> +<a href="#name-copyright-notice" class="section-name selfRef">Copyright Notice</a> + </h2> +<p id="section-boilerplate.2-1"> + Copyright (c) 2026 IETF Trust and the persons identified as the + document authors. All rights reserved.<a href="#section-boilerplate.2-1" class="pilcrow">¶</a></p> +<p id="section-boilerplate.2-2"> + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (<span><a href="https://trustee.ietf.org/license-info">https://trustee.ietf.org/license-info</a></span>) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document.<a href="#section-boilerplate.2-2" class="pilcrow">¶</a></p> +</section> +</div> +<div id="toc"> +<section id="section-toc.1"> + <a href="#" onclick="scroll(0,0)" class="toplink">▲</a><h2 id="name-table-of-contents"> +<a href="#name-table-of-contents" class="section-name selfRef">Table of Contents</a> + </h2> +<nav class="toc"><ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1"> + <p id="section-toc.1-1.1.1"><a href="#section-1" class="auto internal xref">1</a>. <a href="#name-introduction" class="internal xref">Introduction</a></p> +<ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.1"> + <p id="section-toc.1-1.1.2.1.1" class="keepWithNext"><a href="#section-1.1" class="auto internal xref">1.1</a>. <a href="#name-decentralization" class="internal xref">Decentralization</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.2"> + <p id="section-toc.1-1.1.2.2.1" class="keepWithNext"><a href="#section-1.2" class="auto internal xref">1.2</a>. <a href="#name-user-to-user-communication" class="internal xref">User to user communication</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.3"> + <p id="section-toc.1-1.1.2.3.1" class="keepWithNext"><a href="#section-1.3" class="auto internal xref">1.3</a>. <a href="#name-channels" class="internal xref">Channels</a></p> +</li> + </ul> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2"> + <p id="section-toc.1-1.2.1"><a href="#section-2" class="auto internal xref">2</a>. <a href="#name-network-protocol" class="internal xref">Network protocol</a></p> +<ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.1"> + <p id="section-toc.1-1.2.2.1.1"><a href="#section-2.1" class="auto internal xref">2.1</a>. <a href="#name-protocol-data-unit-structur" class="internal xref">Protocol Data Unit Structure</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.2"> + <p id="section-toc.1-1.2.2.2.1"><a href="#section-2.2" class="auto internal xref">2.2</a>. <a href="#name-payload-structure" class="internal xref">Payload structure</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.3"> + <p id="section-toc.1-1.2.2.3.1"><a href="#section-2.3" class="auto internal xref">2.3</a>. <a href="#name-data-types" class="internal xref">Data types</a></p> +<ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.3.2.1"> + <p id="section-toc.1-1.2.2.3.2.1.1"><a href="#section-2.3.1" class="auto internal xref">2.3.1</a>. <a href="#name-numeric-types" class="internal xref">Numeric types</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.3.2.2"> + <p id="section-toc.1-1.2.2.3.2.2.1"><a href="#section-2.3.2" class="auto internal xref">2.3.2</a>. <a href="#name-timestamp" class="internal xref">Timestamp</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.3.2.3"> + <p id="section-toc.1-1.2.2.3.2.3.1"><a href="#section-2.3.3" class="auto internal xref">2.3.3</a>. <a href="#name-string" class="internal xref">String</a></p> +</li> + </ul> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4"> + <p id="section-toc.1-1.2.2.4.1"><a href="#section-2.4" class="auto internal xref">2.4</a>. <a href="#name-payload-types" class="internal xref">Payload types</a></p> +<ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.1"> + <p id="section-toc.1-1.2.2.4.2.1.1"><a href="#section-2.4.1" class="auto internal xref">2.4.1</a>. <a href="#name-success" class="internal xref">Success</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.2"> + <p id="section-toc.1-1.2.2.4.2.2.1"><a href="#section-2.4.2" class="auto internal xref">2.4.2</a>. <a href="#name-error" class="internal xref">Error</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.3"> + <p id="section-toc.1-1.2.2.4.2.3.1"><a href="#section-2.4.3" class="auto internal xref">2.4.3</a>. <a href="#name-handshake" class="internal xref">Handshake</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.4"> + <p id="section-toc.1-1.2.2.4.2.4.1"><a href="#section-2.4.4" class="auto internal xref">2.4.4</a>. <a href="#name-auth" class="internal xref">Auth</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.5"> + <p id="section-toc.1-1.2.2.4.2.5.1"><a href="#section-2.4.5" class="auto internal xref">2.4.5</a>. <a href="#name-message" class="internal xref">Message</a></p> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.4.2.6"> + <p id="section-toc.1-1.2.2.4.2.6.1"><a href="#section-2.4.6" class="auto internal xref">2.4.6</a>. <a href="#name-test" class="internal xref">Test</a></p> +</li> + </ul> +</li> + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.5"> + <p id="section-toc.1-1.2.2.5.1"><a href="#section-2.5" class="auto internal xref">2.5</a>. <a href="#name-sequential-operations" class="internal xref">Sequential operations</a></p> +<ul class="compact toc ulBare ulEmpty"> +<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2.2.5.2.1"> + <p id="section-toc.1-1.2.2.5.2.1.1"><a href="#section-2.5.1" class="auto internal xref">2.5.1</a>. <a href="#name-connection-initialization" class="internal xref">Connection initialization</a></p> +</li> + </ul> +</li> + </ul> +</li> + </ul> +</nav> +</section> +</div> +<div id="introduction"> +<section id="section-1"> + <h2 id="name-introduction"> +<a href="#section-1" class="section-number selfRef">1. </a><a href="#name-introduction" class="section-name selfRef">Introduction</a> + </h2> +<p id="section-1-1">SOLEC is currently under development for PWR group project and as part of my +engineering thesis.<a href="#section-1-1" class="pilcrow">¶</a></p> +<p id="section-1-2">System of Lightweight Electronic Communication or SOLEC is a system for +decentralised communication designed for low-speed networks. It uses binary +protocol to keep required bandwidth as low as possible.<a href="#section-1-2" class="pilcrow">¶</a></p> +<p id="section-1-3">Current implementation works on top of TCP/IP stack. In future, SOLEC will be +adapted to work over LoRa.<a href="#section-1-3" class="pilcrow">¶</a></p> +<div id="decentralization"> +<section id="section-1.1"> + <h3 id="name-decentralization"> +<a href="#section-1.1" class="section-number selfRef">1.1. </a><a href="#name-decentralization" class="section-name selfRef">Decentralization</a> + </h3> +<p id="section-1.1-1">Recurring problem with modern day instant messaging is its centralization. +SOLEC solves is it in similair fashion to XMPP or SMTP. SOLEC servers exchange +messages between each other so the users using server A can reach out users +using server B.<a href="#section-1.1-1" class="pilcrow">¶</a></p> +</section> +</div> +<div id="user-to-user-communication"> +<section id="section-1.2"> + <h3 id="name-user-to-user-communication"> +<a href="#section-1.2" class="section-number selfRef">1.2. </a><a href="#name-user-to-user-communication" class="section-name selfRef">User to user communication</a> + </h3> +<p id="section-1.2-1">User can exchange messages with other users of the network if they are both in +their <em>contacts</em> group. Messages from untrusted users are not forwarded by the +server. If users are using different servers chat history is stored on both.<a href="#section-1.2-1" class="pilcrow">¶</a></p> +</section> +</div> +<div id="channels"> +<section id="section-1.3"> + <h3 id="name-channels"> +<a href="#section-1.3" class="section-number selfRef">1.3. </a><a href="#name-channels" class="section-name selfRef">Channels</a> + </h3> +<p id="section-1.3-1">Message can be send to a group of users called channel. Channels settings and +history is stored on a specific server. Users can access channels from servers +other than their own. To receive channel messages user have to join specific +channel.<a href="#section-1.3-1" class="pilcrow">¶</a></p> +</section> +</div> +</section> +</div> +<div id="network-protocol"> +<section id="section-2"> + <h2 id="name-network-protocol"> +<a href="#section-2" class="section-number selfRef">2. </a><a href="#name-network-protocol" class="section-name selfRef">Network protocol</a> + </h2> +<p id="section-2-1">In current version session is provided by TCP connection. Security of +client-server connection can be achieved using TLS.<a href="#section-2-1" class="pilcrow">¶</a></p> +<div id="protocol-data-unit-structure"> +<section id="section-2.1"> + <h3 id="name-protocol-data-unit-structur"> +<a href="#section-2.1" class="section-number selfRef">2.1. </a><a href="#name-protocol-data-unit-structur" class="section-name selfRef">Protocol Data Unit Structure</a> + </h3> +<p id="section-2.1-1">SOLEC is using Type Length Value (TLV) structure for data exchange.<a href="#section-2.1-1" class="pilcrow">¶</a></p> +<div class="lang-ascii-art sourcecode" id="section-2.1-2"> +<pre> 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | Payload ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.1-2" class="pilcrow">¶</a> +</div> +<p id="section-2.1-3">Figure: SOLEC PDU Layout<a href="#section-2.1-3" class="pilcrow">¶</a></p> +<ul class="normal"> +<li class="normal" id="section-2.1-4.1"> + <p id="section-2.1-4.1.1">Type (8): +Payload type is indicated by 1 octed which gives 256 types that can be +represented.<a href="#section-2.1-4.1.1" class="pilcrow">¶</a></p> +</li> + <li class="normal" id="section-2.1-4.2"> + <p id="section-2.1-4.2.1">Length (16): +Payload length is 2 octets. It indicates lenght of the payload field. +The length does not include type and length fields.<a href="#section-2.1-4.2.1" class="pilcrow">¶</a></p> +</li> + <li class="normal" id="section-2.1-4.3"> + <p id="section-2.1-4.3.1">Payload (variable): +Payload stores set of fields determined by its type.<a href="#section-2.1-4.3.1" class="pilcrow">¶</a></p> +</li> + </ul> +</section> +</div> +<div id="payload-structure"> +<section id="section-2.2"> + <h3 id="name-payload-structure"> +<a href="#section-2.2" class="section-number selfRef">2.2. </a><a href="#name-payload-structure" class="section-name selfRef">Payload structure</a> + </h3> +<p id="section-2.2-1">Payload usually consist of one or more data fields but it is possible for +payload to be empty. Some payload types are used only to signal some event and +does not carry any data.<a href="#section-2.2-1" class="pilcrow">¶</a></p> +</section> +</div> +<div id="data-types"> +<section id="section-2.3"> + <h3 id="name-data-types"> +<a href="#section-2.3" class="section-number selfRef">2.3. </a><a href="#name-data-types" class="section-name selfRef">Data types</a> + </h3> +<p id="section-2.3-1">Data typres are basic types that are used in construction of more comples +payload types.<a href="#section-2.3-1" class="pilcrow">¶</a></p> +<div id="numeric-types"> +<section id="section-2.3.1"> + <h4 id="name-numeric-types"> +<a href="#section-2.3.1" class="section-number selfRef">2.3.1. </a><a href="#name-numeric-types" class="section-name selfRef">Numeric types</a> + </h4> +<p id="section-2.3.1-1">Numeric types are Big-Endian. Numeric types names are taken from <a href="https://go.dev/ref/spec#Numeric_types">Go language +spec</a>. Following types are in use:<a href="#section-2.3.1-1" class="pilcrow">¶</a></p> +<ul class="compact"> +<li class="compact" id="section-2.3.1-2.1">uint8<a href="#section-2.3.1-2.1" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.3.1-2.2">uint16<a href="#section-2.3.1-2.2" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.3.1-2.3">uint32<a href="#section-2.3.1-2.3" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.3.1-2.4">uint64<a href="#section-2.3.1-2.4" class="pilcrow">¶</a> +</li> + </ul> +</section> +</div> +<div id="timestamp"> +<section id="section-2.3.2"> + <h4 id="name-timestamp"> +<a href="#section-2.3.2" class="section-number selfRef">2.3.2. </a><a href="#name-timestamp" class="section-name selfRef">Timestamp</a> + </h4> +<p id="section-2.3.2-1">Uint64 containing Unix timestamp in UTC timezone.<a href="#section-2.3.2-1" class="pilcrow">¶</a></p> +<div class="lang-ascii-art sourcecode" id="section-2.3.2-2"> +<pre> 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.3.2-2" class="pilcrow">¶</a> +</div> +</section> +</div> +<div id="string"> +<section id="section-2.3.3"> + <h4 id="name-string"> +<a href="#section-2.3.3" class="section-number selfRef">2.3.3. </a><a href="#name-string" class="section-name selfRef">String</a> + </h4> +<p id="section-2.3.3-1">String is prefixed with two octets indicating number of bytes that it occupies. +Text is encoded using UTF-8.<a href="#section-2.3.3-1" class="pilcrow">¶</a></p> +<div class="lang-ascii-art sourcecode" id="section-2.3.3-2"> +<pre> 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Length | UTF-8 string ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.3.3-2" class="pilcrow">¶</a> +</div> +<p id="section-2.3.3-3">Figure: String Layout<a href="#section-2.3.3-3" class="pilcrow">¶</a></p> +</section> +</div> +</section> +</div> +<div id="payload-types"> +<section id="section-2.4"> + <h3 id="name-payload-types"> +<a href="#section-2.4" class="section-number selfRef">2.4. </a><a href="#name-payload-types" class="section-name selfRef">Payload types</a> + </h3> +<p id="section-2.4-1">Payload type attributes describes following characteristics:<a href="#section-2.4-1" class="pilcrow">¶</a></p> +<ul class="compact"> +<li class="compact" id="section-2.4-2.1">R - Reserved: implementattion should ignore payloads of this type<a href="#section-2.4-2.1" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.4-2.2">S - Server: can be send only by a server<a href="#section-2.4-2.2" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.4-2.3">C - Client: can be send only by a client<a href="#section-2.4-2.3" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.4-2.4">E - Empty: signals an event but does not carry any data<a href="#section-2.4-2.4" class="pilcrow">¶</a> +</li> + </ul> +<table class="center" id="table-1"> + <caption><a href="#table-1" class="selfRef">Table 1</a></caption> +<thead> + <tr> + <th class="text-left" rowspan="1" colspan="1">Type</th> + <th class="text-left" rowspan="1" colspan="1">Name</th> + <th class="text-left" rowspan="1" colspan="1">Attributes</th> + </tr> + </thead> + <tbody> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x00</td> + <td class="text-left" rowspan="1" colspan="1"></td> + <td class="text-left" rowspan="1" colspan="1">R</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x01</td> + <td class="text-left" rowspan="1" colspan="1">Success</td> + <td class="text-left" rowspan="1" colspan="1">SCE</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x02</td> + <td class="text-left" rowspan="1" colspan="1">Error</td> + <td class="text-left" rowspan="1" colspan="1">S</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x03</td> + <td class="text-left" rowspan="1" colspan="1">Handshake</td> + <td class="text-left" rowspan="1" colspan="1">SC</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x04</td> + <td class="text-left" rowspan="1" colspan="1">Auth</td> + <td class="text-left" rowspan="1" colspan="1">C</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x05</td> + <td class="text-left" rowspan="1" colspan="1">Message</td> + <td class="text-left" rowspan="1" colspan="1">SC</td> + </tr> + <tr> + <td class="text-left" rowspan="1" colspan="1">0xFF</td> + <td class="text-left" rowspan="1" colspan="1">Test</td> + <td class="text-left" rowspan="1" colspan="1">R</td> + </tr> + </tbody> + </table> +<div id="success"> +<section id="section-2.4.1"> + <h4 id="name-success"> +<a href="#section-2.4.1" class="section-number selfRef">2.4.1. </a><a href="#name-success" class="section-name selfRef">Success</a> + </h4> +<p id="section-2.4.1-1">Payload is always empty for this type.<a href="#section-2.4.1-1" class="pilcrow">¶</a></p> +</section> +</div> +<div id="error"> +<section id="section-2.4.2"> + <h4 id="name-error"> +<a href="#section-2.4.2" class="section-number selfRef">2.4.2. </a><a href="#name-error" class="section-name selfRef">Error</a> + </h4> +<div class="lang-ascii-art sourcecode" id="section-2.4.2-1"> +<pre> 0 + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + | Error Type | + +-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.4.2-1" class="pilcrow">¶</a> +</div> +<div id="error-types"> +<section id="section-2.4.2.1"> + <h5 id="name-error-types"> +<a href="#section-2.4.2.1" class="section-number selfRef">2.4.2.1. </a><a href="#name-error-types" class="section-name selfRef">Error types</a> + </h5> +<table class="center" id="table-2"> + <caption><a href="#table-2" class="selfRef">Table 2</a></caption> +<thead> + <tr> + <th class="text-left" rowspan="1" colspan="1">Type</th> + <th class="text-left" rowspan="1" colspan="1">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td class="text-left" rowspan="1" colspan="1">0x01</td> + <td class="text-left" rowspan="1" colspan="1">Auth failed. Invalid username or password.</td> + </tr> + </tbody> + </table> +</section> +</div> +</section> +</div> +<div id="handshake"> +<section id="section-2.4.3"> + <h4 id="name-handshake"> +<a href="#section-2.4.3" class="section-number selfRef">2.4.3. </a><a href="#name-handshake" class="section-name selfRef">Handshake</a> + </h4> +<div class="lang-ascii-art sourcecode" id="section-2.4.3-1"> +<pre> 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ver_major | ver_minor | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.4.3-1" class="pilcrow">¶</a> +</div> +</section> +</div> +<div id="auth"> +<section id="section-2.4.4"> + <h4 id="name-auth"> +<a href="#section-2.4.4" class="section-number selfRef">2.4.4. </a><a href="#name-auth" class="section-name selfRef">Auth</a> + </h4> +<div class="lang-ascii-art sourcecode" id="section-2.4.4-1"> +<pre> 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | username (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | password (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.4.4-1" class="pilcrow">¶</a> +</div> +</section> +</div> +<div id="message"> +<section id="section-2.4.5"> + <h4 id="name-message"> +<a href="#section-2.4.5" class="section-number selfRef">2.4.5. </a><a href="#name-message" class="section-name selfRef">Message</a> + </h4> +<div class="lang-ascii-art sourcecode" id="section-2.4.5-1"> +<pre> 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source_address (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | target_address (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | message_content (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.4.5-1" class="pilcrow">¶</a> +</div> +</section> +</div> +<div id="test"> +<section id="section-2.4.6"> + <h4 id="name-test"> +<a href="#section-2.4.6" class="section-number selfRef">2.4.6. </a><a href="#name-test" class="section-name selfRef">Test</a> + </h4> +<p id="section-2.4.6-1">Test payload is used for encoder and decoders testing. Clients and servers +should ignore this kind of payload.<a href="#section-2.4.6-1" class="pilcrow">¶</a></p> +<div class="lang-ascii-art sourcecode" id="section-2.4.6-2"> +<pre> 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num1 (uint8) | time1 (timestamp) | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| + | | str1 (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num2 (uint16) | str2 (string) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num3 (uint32) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | str3 (string) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num4 (uint64) | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +</pre><a href="#section-2.4.6-2" class="pilcrow">¶</a> +</div> +</section> +</div> +</section> +</div> +<div id="sequential-operations"> +<section id="section-2.5"> + <h3 id="name-sequential-operations"> +<a href="#section-2.5" class="section-number selfRef">2.5. </a><a href="#name-sequential-operations" class="section-name selfRef">Sequential operations</a> + </h3> +<p id="section-2.5-1">Some perations require multiple rounds of communication. +In this case payloads are send in a sequence. Payload that is not part of this +specific operation (for example incomming message) cannot interrupt this process.<a href="#section-2.5-1" class="pilcrow">¶</a></p> +<div id="connection-initialization"> +<section id="section-2.5.1"> + <h4 id="name-connection-initialization"> +<a href="#section-2.5.1" class="section-number selfRef">2.5.1. </a><a href="#name-connection-initialization" class="section-name selfRef">Connection initialization</a> + </h4> +<ul class="compact"> +<li class="compact" id="section-2.5.1-1.1">Client: Initialize TCP connection.<a href="#section-2.5.1-1.1" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.2">Client: Send <em>handshake</em>.<a href="#section-2.5.1-1.2" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.3">Server: If <em>major</em> version of protocol differs close the connection.<a href="#section-2.5.1-1.3" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.4">Server: Otherwise send <em>handshake</em>.<a href="#section-2.5.1-1.4" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.5">Client: Send <em>auth</em>.<a href="#section-2.5.1-1.5" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.6">Server: If user credentials does not match send <em>error</em> with <em>auth_failed</em>.<a href="#section-2.5.1-1.6" class="pilcrow">¶</a> +</li> + <li class="compact" id="section-2.5.1-1.7">Server: Otherwise send <em>success</em>.<a href="#section-2.5.1-1.7" class="pilcrow">¶</a> +</li> + </ul> +</section> +</div> +</section> +</div> +</section> +</div> +<script>const toc = document.getElementById("toc"); +toc.querySelector("h2").addEventListener("click", e => { + toc.classList.toggle("active"); +}); +toc.querySelector("nav").addEventListener("click", e => { + toc.classList.remove("active"); +}); +</script> +</body> +</html> diff --git a/docs/rfc.txt b/docs/rfc.txt new file mode 100644 index 0000000..a53f170 --- /dev/null +++ b/docs/rfc.txt @@ -0,0 +1,267 @@ +SOLEC Working Group bt, Ed. +Internet-Draft RCTT.net +Intended status: Experimental 29 March 2026 +Expires: 30 September 2026 + + + System of Lightweight Electronic Communication + SOLEC + +Abstract + + This document describes working principles, features and network + protocol of SOLEC system. + +Table of Contents + + 1. Introduction + 1.1. Decentralization + 1.2. User to user communication + 1.3. Channels + 2. Network protocol + 2.1. Protocol Data Unit Structure + 2.2. Payload structure + 2.3. Data types + 2.3.1. Numeric types + 2.3.2. Timestamp + 2.3.3. String + 2.4. Payload types + 2.4.1. Success + 2.4.2. Error + 2.4.3. Handshake + 2.4.4. Auth + 2.4.5. Message + 2.4.6. Test + 2.5. Sequential operations + 2.5.1. Connection initialization + +1. Introduction + + SOLEC is currently under development for PWR group project and as + part of my engineering thesis. + + System of Lightweight Electronic Communication or SOLEC is a system + for decentralised communication designed for low-speed networks. It + uses binary protocol to keep required bandwidth as low as possible. + + Current implementation works on top of TCP/IP stack. In future, + SOLEC will be adapted to work over LoRa. + +1.1. Decentralization + + Recurring problem with modern day instant messaging is its + centralization. SOLEC solves is it in similair fashion to XMPP or + SMTP. SOLEC servers exchange messages between each other so the + users using server A can reach out users using server B. + +1.2. User to user communication + + User can exchange messages with other users of the network if they + are both in their _contacts_ group. Messages from untrusted users + are not forwarded by the server. If users are using different + servers chat history is stored on both. + +1.3. Channels + + Message can be send to a group of users called channel. Channels + settings and history is stored on a specific server. Users can + access channels from servers other than their own. To receive + channel messages user have to join specific channel. + +2. Network protocol + + In current version session is provided by TCP connection. Security + of client-server connection can be achieved using TLS. + +2.1. Protocol Data Unit Structure + + SOLEC is using Type Length Value (TLV) structure for data exchange. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | Payload ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure: SOLEC PDU Layout + + * Type (8): Payload type is indicated by 1 octed which gives 256 + types that can be represented. + + * Length (16): Payload length is 2 octets. It indicates lenght of + the payload field. The length does not include type and length + fields. + + * Payload (variable): Payload stores set of fields determined by its + type. + +2.2. Payload structure + + Payload usually consist of one or more data fields but it is possible + for payload to be empty. Some payload types are used only to signal + some event and does not carry any data. + +2.3. Data types + + Data typres are basic types that are used in construction of more + comples payload types. + +2.3.1. Numeric types + + Numeric types are Big-Endian. Numeric types names are taken from Go + language spec (https://go.dev/ref/spec#Numeric_types). Following + types are in use: + + * uint8 + * uint16 + * uint32 + * uint64 + +2.3.2. Timestamp + + Uint64 containing Unix timestamp in UTC timezone. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Timestamp | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.3.3. String + + String is prefixed with two octets indicating number of bytes that it + occupies. Text is encoded using UTF-8. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Length | UTF-8 string ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure: String Layout + +2.4. Payload types + + Payload type attributes describes following characteristics: + + * R - Reserved: implementattion should ignore payloads of this type + * S - Server: can be send only by a server + * C - Client: can be send only by a client + * E - Empty: signals an event but does not carry any data + + +======+===========+============+ + | Type | Name | Attributes | + +======+===========+============+ + | 0x00 | | R | + +------+-----------+------------+ + | 0x01 | Success | SCE | + +------+-----------+------------+ + | 0x02 | Error | S | + +------+-----------+------------+ + | 0x03 | Handshake | SC | + +------+-----------+------------+ + | 0x04 | Auth | C | + +------+-----------+------------+ + | 0x05 | Message | SC | + +------+-----------+------------+ + | 0xFF | Test | R | + +------+-----------+------------+ + + Table 1 + +2.4.1. Success + + Payload is always empty for this type. + +2.4.2. Error + + 0 + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + | Error Type | + +-+-+-+-+-+-+-+-+ + +2.4.2.1. Error types + + +======+=============================================+ + | Type | Description | + +======+=============================================+ + | 0x01 | Auth failed. Invalid username or password. | + +------+---------------------------------------------+ + + Table 2 + +2.4.3. Handshake + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ver_major | ver_minor | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.4.4. Auth + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | username (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | password (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.4.5. Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source_address (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | target_address (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | message_content (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.4.6. Test + + Test payload is used for encoder and decoders testing. Clients and + servers should ignore this kind of payload. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num1 (uint8) | time1 (timestamp) | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| + | | str1 (string) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num2 (uint16) | str2 (string) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num3 (uint32) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | str3 (string) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | num4 (uint64) | + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +2.5. Sequential operations + + Some perations require multiple rounds of communication. In this + case payloads are send in a sequence. Payload that is not part of + this specific operation (for example incomming message) cannot + interrupt this process. + +2.5.1. Connection initialization + + * Client: Initialize TCP connection. + * Client: Send _handshake_. + * Server: If _major_ version of protocol differs close the + connection. + * Server: Otherwise send _handshake_. + * Client: Send _auth_. + * Server: If user credentials does not match send _error_ with + _auth_failed_. + * Server: Otherwise send _success_. |
