commit 2f65df7dc234fe1d8eb76032201c05564baf0fdb parent acac9bd765f31859624907f10ad20efc8183554a Author: Martin Schanzenbach <schanzen@gnunet.org> Date: Sun, 31 Jul 2022 18:20:53 +0200 add developer handbook from import Diffstat:
| A | _static/images/ascension_interaction.png | | | 0 | |
| A | _static/images/ascension_ssd.png | | | 0 | |
| A | _static/images/daemon_lego_block.png | | | 0 | |
| A | _static/images/daemon_lego_block.svg | | | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/gns.dot | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/gns.eps | | | 585 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/gns.jpg | | | 0 | |
| A | _static/images/gnunet-0-10-peerinfo.png | | | 0 | |
| A | _static/images/gnunet-fs-gtk-0-10-star-tab.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-download-area.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-menu.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-publish-editing.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-publish-select.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-publish-with-file.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-publish-with-file_0.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-publish.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-published.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs-search.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-fs.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-gns-a-done.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-gns-a.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-gns.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-identity.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-search-selected.png | | | 0 | |
| A | _static/images/gnunet-gtk-0-10-traffic.png | | | 0 | |
| A | _static/images/gnunet-namestore-gtk-phone.png | | | 0 | |
| A | _static/images/gnunet-namestore-gtk-vpn.png | | | 0 | |
| A | _static/images/gnunet-setup-exit.png | | | 0 | |
| A | _static/images/gnunet-tutorial-service.png | | | 0 | |
| A | _static/images/gnunet-tutorial-system.png | | | 0 | |
| A | _static/images/iceweasel-preferences.png | | | 0 | |
| A | _static/images/iceweasel-proxy.png | | | 0 | |
| A | _static/images/lego_stack.svg | | | 737 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/messenger_room.png | | | 0 | |
| A | _static/images/messenger_room.svg | | | 501 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/service_lego_block.png | | | 0 | |
| A | _static/images/service_lego_block.svg | | | 345 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/service_stack.png | | | 0 | |
| A | _static/images/structure.dot | | | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/tng.dot | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | _static/images/tng.png | | | 0 | |
| M | conf.py | | | 1 | + |
| M | index.md | | | 2 | +- |
| A | man_developers/contributing.rst | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/index.rst | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/repo.rst | | | 260 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/style.rst | | | 152 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/apps.rst | | | 9 | +++++++++ |
| A | man_developers/subsystems/ats/ats.rst | | | 27 | +++++++++++++++++++++++++++ |
| A | man_developers/subsystems/cadet/cadet.rst | | | 150 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/core/core.rst | | | 385 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/corestack.rst | | | 23 | +++++++++++++++++++++++ |
| A | man_developers/subsystems/deps.rst | | | 100 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/dht/dht.rst | | | 414 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/fs/fs.rst | | | 174 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/gns/gns.rst | | | 616 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/gnsstack.rst | | | 12 | ++++++++++++ |
| A | man_developers/subsystems/hostlist/hostlist.rst | | | 290 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/identity/identity.rst | | | 182 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/index.rst | | | 90 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/messenger/messenger.rst | | | 240 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/namecache/namecache.rst | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/namestore/namestore.rst | | | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/nse/nse.rst | | | 312 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/peerinfo/peerinfo.rst | | | 216 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/peerstore/peerstore.rst | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/regex/regex.rst | | | 152 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/rest/rest.rst | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/revocation/revocation.rst | | | 172 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/rps/rps.rst | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/set/set.rst | | | 336 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/seti/seti.rst | | | 257 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/setops.rst | | | 11 | +++++++++++ |
| A | man_developers/subsystems/setu/setu.rst | | | 231 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/stability.rst | | | 136 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/statistics/statistics.rst | | | 192 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/transport-ng/transport-ng.rst | | | 258 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/transport/transport.rst | | | 843 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | man_developers/subsystems/vpnstack.rst | | | 6 | ++++++ |
| A | man_developers/util/index.rst | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
80 files changed, 9464 insertions(+), 1 deletion(-)
diff --git a/_static/images/ascension_interaction.png b/_static/images/ascension_interaction.png Binary files differ. diff --git a/_static/images/ascension_ssd.png b/_static/images/ascension_ssd.png Binary files differ. diff --git a/_static/images/daemon_lego_block.png b/_static/images/daemon_lego_block.png Binary files differ. diff --git a/_static/images/daemon_lego_block.svg b/_static/images/daemon_lego_block.svg @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg6781" + version="1.1" + inkscape:version="0.48.2 r9819" + sodipodi:docname="New document 58"> + <defs + id="defs6783" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.35" + inkscape:cx="375" + inkscape:cy="520" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1366" + inkscape:window-height="721" + inkscape:window-x="-2" + inkscape:window-y="-3" + inkscape:window-maximized="1" /> + <metadata + id="metadata6786"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + transform="translate(-4.5298577,-148.04661)" + id="g6746"> + <path + style="fill:#5fd38d;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99014676;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 183.84284,595.7683 350.8064,0 0,202.04036 -350.8064,0 z" + id="path6693" + inkscape:connector-curvature="0" /> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.22747946;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6695" + width="66.670067" + height="75.18058" + x="223.74881" + y="737.19458" /> + <rect + y="737.19458" + x="331.83514" + height="67.323441" + width="66.670067" + id="rect6697" + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.10787106;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6699" + width="66.670067" + height="64.373825" + x="434.8707" + y="737.19458" /> + <path + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 223.60976,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + id="path6701" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6703" + d="m 331.69608,736.21851 67.23534,0.3894 0,23.98466 -67.23534,37.68524 z" + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.99090236;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 434.73164,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + id="path6705" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 533.72659,595.02309 56.12366,-29.34622 -1.01015,190.24271 -55.11351,41.45733 z" + id="path6707" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99424875;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 245.46708,566.47881 345.46203,-1.01015 -56.56854,31.31472 -349.50264,-1.01014 z" + id="path6709" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + sodipodi:linespacing="125%" + id="text6715" + y="677.59558" + x="234.35539" + style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="677.59558" + x="234.35539" + id="tspan6717" + sodipodi:role="line">User Interface</tspan></text> + </g> + </g> +</svg> diff --git a/_static/images/gns.dot b/_static/images/gns.dot @@ -0,0 +1,42 @@ +// house = interface towards application +// circle (default) = storage +// diamond = stateless tool +// box = legacy system + +// this is what we have...o +digraph dataflow { +splines = true; + + DNS [shape="box"]; + import [label="gnunet-zoneimport", shape="diamond"]; + namestore; + namecache; + gns [shape="diamond"]; + dns2gns [shape="house"]; + cmdline [label="gnunet-gns", shape="house"]; + libnss_gns [shape="house"]; + proxy [label="gnunet-gns-proxy", shape="house"]; + dht; + zonemaster [shape="diamond"]; + + DNS -> import [label="import"]; + import -> namestore [label="export"]; + + namestore -> zonemaster [label="notifies"]; + zonemaster -> dht [label="publishes"]; + + namestore -> namecache [label="pre-populates"]; + + + + libnss_gns -> cmdline [label="invokes"]; + cmdline -> gns [label="lookup"]; + + dns2gns -> gns [label="lookup"]; + + proxy -> gns [label="lookup"]; + + gns -> namecache [label="uses"]; + gns -> dht [label="queries"]; + +} diff --git a/_static/images/gns.eps b/_static/images/gns.eps @@ -0,0 +1,585 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: graphviz version 2.40.1 (20161225.0304) +%%Title: dataflow +%%Pages: 1 +%%BoundingBox: 36 36 722 428 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval +EncodingVector 45 /hyphen put + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset graphviz 0 0 +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def +/tapered { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw text fitted to its expected width +/alignedtext { % width text + /text exch def + /width exch def + gsave + width 0 gt { + [] 0 setdash + text stringwidth pop width exch sub text length div 0 text ashow + } if + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def +/showpage { } def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +setupLatin1 +%%Page: 1 1 +%%PageBoundingBox: 36 36 722 428 +%%PageOrientation: Portrait +0 0 1 beginpage +gsave +36 36 686 392 boxprim clip newpath +1 1 set_scale 0 rotate 40 40 translate +% DNS +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 137.2989 384 moveto +83.2989 384 lineto +83.2989 348 lineto +137.2989 348 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +96.2989 362.3 moveto 28 (DNS) alignedtext +grestore +% import +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 110.2989 297 moveto +.2008 279 lineto +110.2989 261 lineto +220.397 279 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +58.2989 275.3 moveto 104 (gnunet-zoneimport) alignedtext +grestore +% DNS->import +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 110.2989 347.9735 moveto +110.2989 336.1918 110.2989 320.5607 110.2989 307.1581 curveto +stroke +0 0 0 edgecolor +newpath 113.799 307.0033 moveto +110.2989 297.0034 lineto +106.799 307.0034 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 113.799 307.0033 moveto +110.2989 297.0034 lineto +106.799 307.0034 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +110.2989 318.8 moveto 37 (import) alignedtext +grestore +% namestore +gsave +1 setlinewidth +0 0 0 nodecolor +159.2989 192 47.3916 18 ellipse_path stroke +0 0 0 nodecolor +14 /Times-Roman set_font +130.7989 188.3 moveto 57 (namestore) alignedtext +grestore +% import->namestore +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 119.7466 262.2255 moveto +126.7274 249.831 136.3701 232.7103 144.3867 218.4767 curveto +stroke +0 0 0 edgecolor +newpath 147.5178 220.0495 moveto +149.3756 209.6188 lineto +141.4186 216.6143 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 147.5178 220.0495 moveto +149.3756 209.6188 lineto +141.4186 216.6143 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +138.2989 231.8 moveto 35 (export) alignedtext +grestore +% namecache +gsave +1 setlinewidth +0 0 0 nodecolor +300.2989 105 50.0912 18 ellipse_path stroke +0 0 0 nodecolor +14 /Times-Roman set_font +269.7989 101.3 moveto 61 (namecache) alignedtext +grestore +% namestore->namecache +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 184.1823 176.6464 moveto +206.9544 162.5955 240.8544 141.6785 266.1545 126.0678 curveto +stroke +0 0 0 edgecolor +newpath 268.04 129.0171 moveto +274.7125 120.7873 lineto +264.3642 123.0598 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 268.04 129.0171 moveto +274.7125 120.7873 lineto +264.3642 123.0598 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +238.2989 144.8 moveto 74 (pre-populates) alignedtext +grestore +% zonemaster +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 159.2989 123 moveto +86.5718 105 lineto +159.2989 87 lineto +232.0259 105 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +127.7989 101.3 moveto 63 (zonemaster) alignedtext +grestore +% namestore->zonemaster +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 159.2989 173.9735 moveto +159.2989 162.1918 159.2989 146.5607 159.2989 133.1581 curveto +stroke +0 0 0 edgecolor +newpath 162.799 133.0033 moveto +159.2989 123.0034 lineto +155.799 133.0034 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 162.799 133.0033 moveto +159.2989 123.0034 lineto +155.799 133.0034 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +159.2989 144.8 moveto 41 (notifies) alignedtext +grestore +% gns +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 386.2989 210 moveto +353.957 192 lineto +386.2989 174 lineto +418.6408 192 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +376.7989 188.3 moveto 19 (gns) alignedtext +grestore +% gns->namecache +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 373.8052 180.5028 moveto +366.3078 173.5201 356.6389 164.3674 348.2989 156 curveto +339.8869 147.5605 330.8812 138.1087 322.969 129.6563 curveto +stroke +0 0 0 edgecolor +newpath 325.434 127.1675 moveto +316.0586 122.2327 lineto +320.3103 131.937 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 325.434 127.1675 moveto +316.0586 122.2327 lineto +320.3103 131.937 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +348.2989 144.8 moveto 24 (uses) alignedtext +grestore +% dht +gsave +1 setlinewidth +0 0 0 nodecolor +272.2989 18 27 18 ellipse_path stroke +0 0 0 nodecolor +14 /Times-Roman set_font +263.2989 14.3 moveto 18 (dht) alignedtext +grestore +% gns->dht +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 385.181 174.2737 moveto +383.0587 152.2164 376.9318 114.1509 359.2989 87 curveto +344.9772 64.9477 321.2191 46.8067 302.1458 34.6694 curveto +stroke +0 0 0 edgecolor +newpath 303.8469 31.6069 moveto +293.4925 29.3628 lineto +300.1875 37.5742 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 303.8469 31.6069 moveto +293.4925 29.3628 lineto +300.1875 37.5742 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +376.2989 101.3 moveto 40 (queries) alignedtext +grestore +% dns2gns +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 336.3104 284.5623 moveto +287.2989 297 lineto +238.2874 284.5623 lineto +238.3331 264.4377 lineto +336.2646 264.4377 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +264.7989 275.3 moveto 45 (dns2gns) alignedtext +grestore +% dns2gns->gns +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 304.0929 264.2416 moveto +321.1237 249.2751 347.504 226.0924 365.7671 210.0431 curveto +stroke +0 0 0 edgecolor +newpath 368.323 212.4564 moveto +373.5243 203.2262 lineto +363.7022 207.1983 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 368.323 212.4564 moveto +373.5243 203.2262 lineto +363.7022 207.1983 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +343.2989 231.8 moveto 38 (lookup) alignedtext +grestore +% cmdline +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 478.0186 284.5623 moveto +416.2989 297 lineto +354.5791 284.5623 lineto +354.6367 264.4377 lineto +477.961 264.4377 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +385.7989 275.3 moveto 61 (gnunet-gns) alignedtext +grestore +% cmdline->gns +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 411.2098 264.2416 moveto +406.7547 251.3219 400.1883 232.2795 394.9156 216.9885 curveto +stroke +0 0 0 edgecolor +newpath 398.0825 215.4359 moveto +391.5138 207.1232 lineto +391.4649 217.7179 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 398.0825 215.4359 moveto +391.5138 207.1232 lineto +391.4649 217.7179 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +403.2989 231.8 moveto 38 (lookup) alignedtext +grestore +% libnss_gns +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 475.6981 371.5623 moveto +416.2989 384 lineto +356.8996 371.5623 lineto +356.9551 351.4377 lineto +475.6427 351.4377 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +387.2989 362.3 moveto 58 (libnss_gns) alignedtext +grestore +% libnss_gns->cmdline +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 416.2989 351.2416 moveto +416.2989 339.2263 416.2989 321.9156 416.2989 307.2516 curveto +stroke +0 0 0 edgecolor +newpath 419.799 307.1553 moveto +416.2989 297.1553 lineto +412.799 307.1553 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 419.799 307.1553 moveto +416.2989 297.1553 lineto +412.799 307.1553 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +416.2989 318.8 moveto 43 (invokes) alignedtext +grestore +% proxy +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 677.8617 284.5623 moveto +587.2989 297 lineto +496.7361 284.5623 lineto +496.8206 264.4377 lineto +677.7771 264.4377 lineto +closepath stroke +0 0 0 nodecolor +14 /Times-Roman set_font +538.7989 275.3 moveto 97 (gnunet-gns-proxy) alignedtext +grestore +% proxy->gns +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 553.202 264.2416 moveto +513.9908 247.2697 450.3696 219.7321 414.0521 204.0126 curveto +stroke +0 0 0 edgecolor +newpath 415.1432 200.6711 moveto +404.5757 199.9109 lineto +412.3626 207.0952 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 415.1432 200.6711 moveto +404.5757 199.9109 lineto +412.3626 207.0952 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +499.2989 231.8 moveto 38 (lookup) alignedtext +grestore +% zonemaster->dht +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 177.2041 91.2146 moveto +195.8835 76.8331 225.3438 54.1513 246.5248 37.8438 curveto +stroke +0 0 0 edgecolor +newpath 248.689 40.5947 moveto +254.4775 31.7209 lineto +244.4186 35.0482 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 248.689 40.5947 moveto +254.4775 31.7209 lineto +244.4186 35.0482 lineto +closepath stroke +0 0 0 edgecolor +14 /Times-Roman set_font +223.2989 57.8 moveto 52 (publishes) alignedtext +grestore +endpage +showpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +end +restore +%%EOF diff --git a/_static/images/gns.jpg b/_static/images/gns.jpg Binary files differ. diff --git a/_static/images/gnunet-0-10-peerinfo.png b/_static/images/gnunet-0-10-peerinfo.png Binary files differ. diff --git a/_static/images/gnunet-fs-gtk-0-10-star-tab.png b/_static/images/gnunet-fs-gtk-0-10-star-tab.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-download-area.png b/_static/images/gnunet-gtk-0-10-download-area.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-menu.png b/_static/images/gnunet-gtk-0-10-fs-menu.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-publish-editing.png b/_static/images/gnunet-gtk-0-10-fs-publish-editing.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-publish-select.png b/_static/images/gnunet-gtk-0-10-fs-publish-select.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-publish-with-file.png b/_static/images/gnunet-gtk-0-10-fs-publish-with-file.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-publish-with-file_0.png b/_static/images/gnunet-gtk-0-10-fs-publish-with-file_0.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-publish.png b/_static/images/gnunet-gtk-0-10-fs-publish.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-published.png b/_static/images/gnunet-gtk-0-10-fs-published.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs-search.png b/_static/images/gnunet-gtk-0-10-fs-search.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-fs.png b/_static/images/gnunet-gtk-0-10-fs.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-gns-a-done.png b/_static/images/gnunet-gtk-0-10-gns-a-done.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-gns-a.png b/_static/images/gnunet-gtk-0-10-gns-a.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-gns.png b/_static/images/gnunet-gtk-0-10-gns.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-identity.png b/_static/images/gnunet-gtk-0-10-identity.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-search-selected.png b/_static/images/gnunet-gtk-0-10-search-selected.png Binary files differ. diff --git a/_static/images/gnunet-gtk-0-10-traffic.png b/_static/images/gnunet-gtk-0-10-traffic.png Binary files differ. diff --git a/_static/images/gnunet-namestore-gtk-phone.png b/_static/images/gnunet-namestore-gtk-phone.png Binary files differ. diff --git a/_static/images/gnunet-namestore-gtk-vpn.png b/_static/images/gnunet-namestore-gtk-vpn.png Binary files differ. diff --git a/_static/images/gnunet-setup-exit.png b/_static/images/gnunet-setup-exit.png Binary files differ. diff --git a/_static/images/gnunet-tutorial-service.png b/_static/images/gnunet-tutorial-service.png Binary files differ. diff --git a/_static/images/gnunet-tutorial-system.png b/_static/images/gnunet-tutorial-system.png Binary files differ. diff --git a/_static/images/iceweasel-preferences.png b/_static/images/iceweasel-preferences.png Binary files differ. diff --git a/_static/images/iceweasel-proxy.png b/_static/images/iceweasel-proxy.png Binary files differ. diff --git a/_static/images/lego_stack.svg b/_static/images/lego_stack.svg @@ -0,0 +1,737 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="System.svg"> + <defs + id="defs4"> + <linearGradient + id="linearGradient6602"> + <stop + style="stop-color:#df8060;stop-opacity:1;" + offset="0" + id="stop6604" /> + <stop + style="stop-color:#df8002;stop-opacity:0;" + offset="1" + id="stop6606" /> + </linearGradient> + <linearGradient + id="linearGradient4392" + osb:paint="solid"> + <stop + style="stop-color:#faf6a6;stop-opacity:1;" + offset="0" + id="stop4394" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="883.99395 : 559.99673 : 1" + inkscape:vp_y="13.319386 : 993.87659 : 0" + inkscape:vp_z="285.3157 : 504.79962 : 1" + inkscape:persp3d-origin="481.39556 : 281.96355 : 1" + id="perspective3070" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="76.097926 : 349.87282 : 1" + inkscape:vp_y="-13.319386 : 979.366 : 0" + inkscape:vp_z="752.55793 : 376.31441 : 1" + inkscape:persp3d-origin="373.64045 : 350.98006 : 1" + id="perspective3012" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.98994949" + inkscape:cx="322.06882" + inkscape:cy="568.82291" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="846" + inkscape:window-height="963" + inkscape:window-x="59" + inkscape:window-y="0" + inkscape:window-maximized="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="352.03815" + y="-190.12544" + id="text6623" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6625" + x="352.03815" + y="-190.12544" /></text> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="338.40109" + y="-300.73715" + id="text6627" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6629" + x="338.40109" + y="-300.73715" /></text> + <g + style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + id="text6643" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="71.720833" + y="95.747719" + id="text6648" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6650" + x="71.720833" + y="95.747719" /></text> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="262.63965" + y="666.48389" + id="text6711" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6713" + x="262.63965" + y="666.48389" /></text> + <path + inkscape:connector-curvature="0" + id="path3506" + d="m 198.00647,673.76257 236.93358,0 0,158.2919 -236.93358,0 z" + style="fill:#000000;fill-opacity:1;stroke:#faf6a2;stroke-width:1.44768786;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path3432" + d="m 169.32669,654.90334 464.83332,-2.26992 -33.76593,25.73079 -483.97287,-0.12904 z" + style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.18398547;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.35822594;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3416" + width="28.495705" + height="172.2845" + x="464.19418" + y="518.96954" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.36876941;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3414" + width="34.729141" + height="170.67587" + x="340.86124" + y="517.93475" /> + <path + style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.04969239;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 246.8138,499.06358 386.50295,-0.94821 -41.88736,26.04231 -413.96081,0 z" + id="rect6568-0" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:1.49989259;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 276.05867,399.52042 323.05541,0 0,124.61741 -323.05541,0 z" + id="rect5973" + inkscape:connector-curvature="0" /> + <path + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 599.16863,399.06078 34.35465,-18.10059 0,117.34068 -34.35465,25.57066 z" + id="rect6542" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <rect + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.50087094;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6557" + width="322.88623" + height="30.529778" + x="276.67755" + y="368.99368" /> + <path + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.50882494;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 598.94047,368.99367 34.58281,-16.82253 0,28.66061 -34.58281,18.06864 z" + id="rect6561" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6564" + d="m 598.94047,369.07046 34.30741,-17.12981 0,29.18412 -34.30741,18.39868 z" + style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + inkscape:transform-center-x="-70.147578" + inkscape:transform-center-y="15.429055" /> + <path + style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.47079194;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 330.2508,353.23478 302.87005,-0.62306 -38.33414,16.82253 -318.87597,0 z" + id="rect6568" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="391.63083" + y="461.858" + id="text6656" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan6658" + x="391.63083" + y="461.858">Service</tspan></text> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6707" + d="m 598.75503,244.83802 34.98432,-18.10059 0.26082,125.2709 -35.24514,17.64044 z" + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6709" + d="m 419.07032,228.1132 214.71185,-1.24611 -34.63196,19.9378 L 381.29,246.18184 z" + style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.23655474;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <rect + style="fill:#5fd38d;fill-opacity:1;stroke:#c48069;stroke-width:1.23640049;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect7224" + width="217.86653" + height="122.74216" + x="381.70358" + y="246.25151" /> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="409.16376" + y="302.05649" + id="text6715" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan6717" + x="409.16376" + y="302.05649">User Interface</tspan></text> + <g + id="g7219" + transform="matrix(0.62334353,0,0,0.61679464,281.18563,257.70936)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect6571" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text6631" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan6633" + sodipodi:role="line">API</tspan></text> + </g> + <g + transform="matrix(0.62334353,0,0,0.61679464,344.78251,257.70936)" + id="g7226"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect7228" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text7230" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7232" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <g + id="g7234" + transform="matrix(0.62334353,0,0,0.61679464,409.3239,257.70936)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect7236" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text7238" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan7240" + sodipodi:role="line">API</tspan></text> + </g> + <g + transform="matrix(0.62334353,0,0,0.61679464,175.75806,412.85048)" + id="g7242"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect7244" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text7246" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7248" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <g + id="g7250" + transform="matrix(0.62334353,0,0,0.61679464,240.79871,413.29105)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect7252" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text7254" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan7256" + sodipodi:role="line">API</tspan></text> + </g> + <g + transform="matrix(0.62334353,0,0,0.61679464,303.79756,412.40991)" + id="g7258"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect7260" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text7262" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7264" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <g + id="g7266" + transform="matrix(0.62334353,0,0,0.61679464,369.88148,412.40991)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect7268" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text7270" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan7272" + sodipodi:role="line">API</tspan></text> + </g> + <path + style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91879815;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 478.56081,554.09281 121.22633,0 0,124.61741 -121.22633,0 z" + id="rect5973-1" + inkscape:connector-curvature="0" /> + <g + transform="matrix(0.62334353,0,0,0.61679464,422.424,566.60858)" + id="g3474"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3476" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text3478" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3480" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <path + style="fill:#ffe680;fill-opacity:1;stroke:#faf6a2;stroke-width:1.18771458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 599.60339,554.02055 33.72575,-29.55535 0.88568,128.35487 -34.61143,26.01123 z" + id="rect6542-8" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6564-2" + d="m 598.92998,524.03024 34.30741,-25.94116 0,26.5407 -34.30741,29.85344 z" + style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + inkscape:transform-center-x="-70.147578" + inkscape:transform-center-y="15.429055" /> + <path + inkscape:transform-center-y="15.492457" + inkscape:transform-center-x="-70.147578" + style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51245213;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 598.92998,524.13683 34.30741,-26.04775 0,26.64977 -34.30741,29.97611 z" + id="path3402" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path3404" + d="m 599.82047,678.2289 34.30741,-25.94116 0,26.5407 -34.30741,34.25912 z" + style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + inkscape:transform-center-x="-70.147578" + inkscape:transform-center-y="15.429055" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path3406" + d="m 600.04863,707.77865 33.90941,-29.55535 0.89049,128.35487 -34.7999,26.01123 z" + style="fill:#37c837;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + inkscape:connector-curvature="0" + id="path3410" + d="m 356.56358,554.09281 120.92249,0 0,124.19268 -120.92249,0 z" + style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91608089;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11023378;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 177.52518,554.09281 177.51841,0 0,124.25702 -177.51841,0 z" + id="path3412" + inkscape:connector-curvature="0" /> + <rect + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.11264122;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6557-7" + width="177.44882" + height="30.529778" + x="177.65657" + y="523.95343" /> + <rect + y="678.1521" + x="116.73995" + height="29.53463" + width="177.54182" + id="rect3408" + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.09464383;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <rect + y="523.95343" + x="356.55023" + height="30.529778" + width="120.86897" + id="rect3420" + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <rect + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3422" + width="120.86897" + height="30.529778" + x="478.54919" + y="523.95343" /> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="372.34232" + y="622.53217" + id="text6656-2" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan6658-2" + x="372.34232" + y="622.53217">Service</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3424" + y="622.53217" + x="220.56013" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve" + transform="scale(1.0052948,0.9947331)"><tspan + y="622.53217" + x="220.56013" + id="tspan3426" + sodipodi:role="line">Service</tspan></text> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="493.85532" + y="622.54492" + id="text3428" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan3430" + x="493.85532" + y="622.54492">Service</tspan></text> + <g + id="g3434" + transform="matrix(0.62334353,0,0,0.61679464,120.10238,566.60858)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect3436" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text3438" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan3440" + sodipodi:role="line">API</tspan></text> + </g> + <g + transform="matrix(0.62334353,0,0,0.61679464,181.54625,566.60858)" + id="g3442"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3444" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text3446" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3448" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <g + id="g3450" + transform="matrix(0.62334353,0,0,0.61679464,242.09962,566.60858)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect3452" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text3454" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan3456" + sodipodi:role="line">API</tspan></text> + </g> + <g + transform="matrix(0.62334353,0,0,0.61679464,303.54348,566.60858)" + id="g3458"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3460" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text3462" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3464" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <g + id="g3466" + transform="matrix(0.62334353,0,0,0.61679464,362.76112,566.60858)"> + <rect + y="119.99139" + x="198.49498" + height="60.609154" + width="66.670067" + id="rect3468" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text3470" + y="160.39748" + x="206.07112" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="206.07112" + id="tspan3472" + sodipodi:role="line">API</tspan></text> + </g> + <path + style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11993289;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 420.2626,707.53388 180.11119,0 0,124.61741 -180.11119,0 z" + id="path3490" + inkscape:connector-curvature="0" /> + <g + transform="matrix(0.62334353,0,0,0.61679464,62.665728,566.60858)" + id="g3492"> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3494" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text3496" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3498" + x="206.07112" + y="160.39748">API</tspan></text> + </g> + <path + inkscape:connector-curvature="0" + id="path3500" + d="m 116.52597,707.54132 177.63643,0 0,124.61741 -177.63643,0 z" + style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11221218;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.92545629;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 295.65636,707.63061 122.98965,0 0,124.61741 -122.98965,0 z" + id="path3502" + inkscape:connector-curvature="0" /> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="162.54019" + y="779.76184" + id="text3508" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan3510" + x="162.54019" + y="779.76184">Service</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3512" + y="779.7619" + x="313.56918" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve" + transform="scale(1.0052948,0.9947331)"><tspan + y="779.7619" + x="313.56918" + id="tspan3514" + sodipodi:role="line">Service</tspan></text> + <text + xml:space="preserve" + style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="465.48401" + y="779.7619" + id="text3516" + sodipodi:linespacing="125%" + transform="scale(1.0052948,0.9947331)"><tspan + sodipodi:role="line" + id="tspan3518" + x="465.48401" + y="779.7619">Service</tspan></text> + <rect + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91063529;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3520" + width="122.86946" + height="29.53463" + x="295.75125" + y="678.1521" /> + <rect + y="678.1521" + x="420.27423" + height="29.53463" + width="179.80205" + id="rect3522" + style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.10158956;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + </g> +</svg> diff --git a/_static/images/messenger_room.png b/_static/images/messenger_room.png Binary files differ. diff --git a/_static/images/messenger_room.svg b/_static/images/messenger_room.svg @@ -0,0 +1,501 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="598.63586mm" + height="519.30621mm" + viewBox="0 0 598.63586 519.30621" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="messenger_room.svg" + inkscape:export-filename="./messenger_room.png" + inkscape:export-xdpi="50" + inkscape:export-ydpi="50"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.35" + inkscape:cx="1617.1523" + inkscape:cy="893.76504" + inkscape:document-units="mm" + inkscape:current-layer="layer3" + inkscape:document-rotation="0" + showgrid="false" + fit-margin-top="10" + fit-margin-bottom="10" + fit-margin-right="10" + fit-margin-left="10" + lock-margins="true" + inkscape:window-width="2560" + inkscape:window-height="1376" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Layer 2" + style="display:inline" + transform="translate(192.28493,120.40152)"> + <path + style="fill:none;stroke:#000000;stroke-width:3.365;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26.206579,156.45999 97.162749,89.570022 199.7759,120.1979 181.87666,217.7128 89.324169,236.23068 Z" + id="path915" /> + <path + style="fill:none;stroke:#000000;stroke-width:2.665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 181.87666,217.7128 66.26913,94.14707" + id="path1063" /> + <path + style="fill:none;stroke:#000000;stroke-width:2.665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.665, 5.33;stroke-dashoffset:0;stroke-opacity:1" + d="M 309.85632,121.37022 199.7759,120.1979" + id="path1065" /> + <path + style="fill:none;stroke:#000000;stroke-width:2.665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 248.9298,18.638951 199.7759,120.1979" + id="path1067" /> + <path + style="fill:none;stroke:#000000;stroke-width:2.665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -76.608095,107.38658 26.206579,156.45999" + id="path1069" /> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Layer 4" + style="display:inline" + transform="translate(192.28493,120.40152)"> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m -137.76937,77.365523 61.161275,30.021057" + id="path1225" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -20.546549,199.60834 26.206579,156.45999" + id="path1227" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 58.558255,290.12036 89.324168,236.23068 125.2681,294.74464" + id="path1229" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 260.56143,374.91842 -12.41564,-63.05855 67.7611,18.91507" + id="path1231" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 237.39119,194.89545 181.87666,217.7128" + id="path1233" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 199.7759,120.1979 177.22801,54.184954" + id="path1235" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 309.85632,121.37022 61.96594,-12.96636" + id="path1237" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 248.9298,18.638951 229.25585,-38.546188" + id="path1239" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 55.073787,29.185372 42.088961,60.38465" + id="path1241" /> + <path + style="fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.865, 3.73;stroke-dashoffset:0;stroke-opacity:1" + d="M -76.608095,107.38658 -138.56518,130.6705" + id="path1243" /> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(192.28493,120.40152)"> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833" + cx="96.685127" + cy="88.539452" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3" + cx="195.51556" + cy="120.85936" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-5" + cx="183.12799" + cy="214.72444" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-6" + cx="92.202576" + cy="236.97336" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-2" + cx="26.400755" + cy="158.9449" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3-1" + cx="309.42667" + cy="120.44005" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3-2" + cx="248.5799" + cy="19.344702" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3-7" + cx="-74.235405" + cy="107.76899" + r="20" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3-0" + cx="249.89246" + cy="310.73776" + r="20" /> + <path + style="display:inline;fill:none;stroke:#000000;stroke-width:1.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 318.33679,228.47452 61.96594,-12.96636" + id="path1237-2" /> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.265;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:6.265, 12.53;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-3-1-8" + cx="317.90714" + cy="227.54434" + r="20" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.82, 5.64;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-62-9" + width="28.700562" + height="22.81683" + x="366.24039" + y="204.47328" /> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="315.72601" + y="231.38942" + id="text1307-7-3-3-94-3"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-6-6" + x="315.72601" + y="231.38942" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">J</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Layer 3" + transform="translate(192.28493,120.40152)"> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071" + width="28.700562" + height="22.81683" + x="41.152424" + y="17.00181" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-6" + width="28.700562" + height="22.81683" + x="163.24538" + y="40.93095" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-0" + width="28.700562" + height="22.81683" + x="217.0302" + y="-48.476658" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-62" + width="28.700562" + height="22.81683" + x="357.75992" + y="97.368996" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-61" + width="28.700562" + height="22.81683" + x="221.61465" + y="183.89601" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-8" + width="28.700562" + height="22.81683" + x="302.37604" + y="319.27646" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-7" + width="28.700562" + height="22.81683" + x="244.56342" + y="364.67789" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-9" + width="28.700562" + height="22.81683" + x="43.508121" + y="279.02939" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-2" + width="28.700562" + height="22.81683" + x="110.22536" + y="283.7334" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-02" + width="28.700562" + height="22.81683" + x="-35.267426" + y="187.65363" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-3" + width="28.700562" + height="22.81683" + x="-151.39322" + y="66.069321" /> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.82;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.82, 5.64;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-3-7" + width="28.700562" + height="22.81683" + x="-154.87178" + y="119.88663" /> + <g + id="g1600" + transform="translate(-2.9470331,-51.038598)"> + <circle + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.78727;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="path833-6-5" + cx="-161.17276" + cy="336.83234" + r="12.09027" /> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="-140.58682" + y="342.66354" + id="text1307"><tspan + sodipodi:role="line" + id="tspan1305" + x="-140.58682" + y="342.66354" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">Peer</tspan></text> + </g> + <g + id="g1594" + transform="translate(-2.9470331,-54.443235)"> + <rect + style="opacity:0.999;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.96946;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" + id="rect1071-9-9" + width="20.044254" + height="15.935102" + x="-171.19489" + y="365.45282" /> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="-140.78059" + y="379.28705" + id="text1307-7"><tspan + sodipodi:role="line" + id="tspan1305-6" + x="-140.78059" + y="379.28705" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">Application</tspan></text> + </g> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="90.401619" + y="94.499252" + id="text1307-7-3"><tspan + sodipodi:role="line" + id="tspan1305-6-0" + x="90.401619" + y="94.499252" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">A</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="189.63115" + y="126.74821" + id="text1307-7-3-3"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0" + x="189.63115" + y="126.74821" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">C</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="178.83551" + y="220.59999" + id="text1307-7-3-3-9"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-2" + x="178.83551" + y="220.59999" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">F</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="85.772736" + y="242.86221" + id="text1307-7-3-3-5"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-4" + x="85.772736" + y="242.86221" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">G</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="19.824577" + y="164.8027" + id="text1307-7-3-3-0"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-5" + x="19.824577" + y="164.8027" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">H</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="303.32053" + y="126.29786" + id="text1307-7-3-3-94"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-6" + x="303.32053" + y="126.29786" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">D</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="243.4848" + y="25.202511" + id="text1307-7-3-3-92"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-24" + x="243.4848" + y="25.202511" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">B</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="247.20479" + y="316.59558" + id="text1307-7-3-3-7"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-7" + x="247.20479" + y="316.59558" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">I</tspan></text> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="-79.01123" + y="113.64454" + id="text1307-7-3-3-54"><tspan + sodipodi:role="line" + id="tspan1305-6-0-0-8" + x="-79.01123" + y="113.64454" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">E</tspan></text> + <g + id="g1589" + transform="translate(-4.3496791,-53.330521)"> + <path + style="fill:none;stroke:#000000;stroke-width:2.62782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.62782, 5.25564;stroke-dashoffset:1.05113;stroke-opacity:1" + d="m -176.62134,400.99519 30.89715,0.38084" + id="path1521" /> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="-137.64647" + y="406.95029" + id="text1307-7-2"><tspan + sodipodi:role="line" + id="tspan1305-6-1" + x="-137.64647" + y="406.95029" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">Inactive</tspan></text> + </g> + <g + id="g1583" + transform="translate(-4.3496791,-49.693534)"> + <path + style="fill:none;stroke:#000000;stroke-width:2.62782;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.05113;stroke-opacity:1" + d="m -176.62134,420.37019 30.89715,0.38084" + id="path1521-0" /> + <text + xml:space="preserve" + style="font-size:18.1632px;line-height:34.0561px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.340559" + x="-138.78186" + y="426.42728" + id="text1307-7-0"><tspan + sodipodi:role="line" + id="tspan1305-6-5" + x="-138.78186" + y="426.42728" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.1632px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.340559">Active</tspan></text> + </g> + <text + xml:space="preserve" + style="font-size:50.8px;line-height:95.25px;font-family:Primer;-inkscape-font-specification:Primer;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583" + x="42.997746" + y="-77.287262" + id="text1604"><tspan + sodipodi:role="line" + id="tspan1602" + x="42.997746" + y="-77.287262" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.8px;font-family:'Linux Libertine Capitals';-inkscape-font-specification:'Linux Libertine Capitals';stroke-width:0.264583">Room</tspan></text> + </g> +</svg> diff --git a/_static/images/service_lego_block.png b/_static/images/service_lego_block.png Binary files differ. diff --git a/_static/images/service_lego_block.svg b/_static/images/service_lego_block.svg @@ -0,0 +1,345 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.48.2 r9819" + sodipodi:docname="Lego block 3.svg"> + <defs + id="defs4"> + <linearGradient + id="linearGradient6602"> + <stop + style="stop-color:#df8060;stop-opacity:1;" + offset="0" + id="stop6604" /> + <stop + style="stop-color:#df8002;stop-opacity:0;" + offset="1" + id="stop6606" /> + </linearGradient> + <linearGradient + id="linearGradient4392" + osb:paint="solid"> + <stop + style="stop-color:#faf6a6;stop-opacity:1;" + offset="0" + id="stop4394" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="883.99395 : 559.99673 : 1" + inkscape:vp_y="13.319386 : 993.87659 : 0" + inkscape:vp_z="285.3157 : 504.79962 : 1" + inkscape:persp3d-origin="481.39556 : 281.96355 : 1" + id="perspective3070" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="76.097926 : 349.87282 : 1" + inkscape:vp_y="-13.319386 : 979.366 : 0" + inkscape:vp_z="752.55793 : 376.31441 : 1" + inkscape:persp3d-origin="373.64045 : 350.98006 : 1" + id="perspective3012" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.49497475" + inkscape:cx="385.59974" + inkscape:cy="826.03166" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1366" + inkscape:window-height="721" + inkscape:window-x="-2" + inkscape:window-y="-3" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:2.26315212;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 74.934278,230.09308 453.654042,0 0,202.04036 -453.654042,0 z" + id="rect5973" + inkscape:connector-curvature="0" /> + <path + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 528.67583,229.34787 55.11351,-29.34622 0,190.24271 -55.11351,41.45733 z" + id="rect6542" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <rect + style="fill:#d38d5f;fill-opacity:1;stroke:#c48069;stroke-width:2.2674458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6557" + width="454.54535" + height="49.497475" + x="74.764442" + y="180.60052" /> + <path + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.8206054;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 528.30981,180.60052 55.47954,-27.27412 0,46.46702 -55.47954,29.29442 z" + id="rect6561" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6564" + d="m 528.30981,180.72501 55.03773,-27.7723 0,47.31578 -55.03773,29.8295 z" + style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.82476228;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + inkscape:transform-center-x="-70.147578" + inkscape:transform-center-y="15.429055" /> + <path + style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.23265362;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 153.39374,154.33657 430.4643,-1.01015 -54.4837,27.27411 -453.213248,0 z" + id="rect6568" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="352.03815" + y="-190.12544" + id="text6623" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6625" + x="352.03815" + y="-190.12544" /></text> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="338.40109" + y="-300.73715" + id="text6627" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6629" + x="338.40109" + y="-300.73715" /></text> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6571" + width="66.670067" + height="60.609154" + x="198.49498" + y="119.99139" /> + <path + style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98413372;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 265.16503,119.45792 44.95179,-22.465406 0,57.057986 -44.95179,26.55003 z" + id="path6600" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99687159;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 243.06977,97.26295 66.86223,10e-7 -45.08135,22.728439 -66.3557,0 z" + id="path6617" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="206.07112" + y="160.39748" + id="text6631" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6633" + x="206.07112" + y="160.39748">API</tspan></text> + <rect + y="119.99139" + x="313.65237" + height="60.609154" + width="66.670067" + id="rect6573" + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6598" + d="m 379.81735,119.56755 44.95179,-22.425126 0,56.955676 -44.95179,26.50243 z" + style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98235416;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6615" + d="m 358.25117,97.26295 66.89824,10e-7 -45.10563,22.728439 -66.39143,0 z" + style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99740911;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <text + sodipodi:linespacing="125%" + id="text6635" + y="160.39748" + x="322.23865" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + xml:space="preserve"><tspan + y="160.39748" + x="322.23865" + id="tspan6637" + sodipodi:role="line">API</tspan></text> + <rect + style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6575" + width="66.670067" + height="60.609154" + x="428.80978" + y="119.99139" /> + <path + style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98960423;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 494.97474,119.62537 44.95179,-22.589454 0,57.373054 -44.95179,26.69664 z" + id="rect6595" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99399996;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 473.25645,97.26295 66.67007,10e-7 -44.95179,22.728439 -66.16499,0 z" + id="rect6612" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="439.41635" + y="159.89241" + id="text6639" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6641" + x="439.41635" + y="159.89241">API</tspan></text> + <g + style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + id="text6643" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="71.720833" + y="95.747719" + id="text6648" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6650" + x="71.720833" + y="95.747719" /></text> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="176.77669" + y="216.96603" + id="text6652" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6654" + x="176.77669" + y="216.96603">Network Protocol</tspan></text> + <text + xml:space="preserve" + style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="233.34526" + y="312.93051" + id="text6656" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6658" + x="233.34526" + y="312.93051">Service</tspan></text> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.09665918;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6660" + width="66.670067" + height="66.609154" + x="216.67773" + y="371.51938" /> + <rect + y="371.51938" + x="322.74374" + height="64.373825" + width="66.670067" + id="rect6662" + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" + id="rect6664" + width="66.670067" + height="60.609154" + x="423.75903" + y="372.52951" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6666" + d="m 423.61996,372.56359 67.23534,-0.62641 0,19.59587 -68.24549,41.17879 z" + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + id="path6668" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6670" + d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + <path + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" + d="m 216.53869,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + id="path6672" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <text + xml:space="preserve" + style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="262.63965" + y="666.48389" + id="text6711" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6713" + x="262.63965" + y="666.48389" /></text> + <rect + y="371.51938" + x="111.62187" + height="70.798637" + width="66.670067" + id="rect6721" + style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.1615901;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> + <path + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" + id="path6723" + d="m 111.48283,370.54329 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z" + style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" /> + </g> +</svg> diff --git a/_static/images/service_stack.png b/_static/images/service_stack.png Binary files differ. diff --git a/_static/images/structure.dot b/_static/images/structure.dot @@ -0,0 +1,126 @@ +// house = application +// circle (default) = service +// box = daemon +// diamond = library +// black line = dependency +// blue line = extension via plugin +// red line = possibly useful +// dashed = in planning + +// this is what we have...o +digraph dependencies { +splines = true; + + voting [shape=house]; + voting -> consensus; + voting -> identity; + voting -> cadet; + voting -> secretsharing; + secretsharing -> consensus; + + fs [shape=house]; + fs -> dht; + fs -> core; + fs -> datastore; + fs -> cadet; + fs -> ats; + fs -> block [style=dotted,color=blue]; + fs -> identity; + exit [shape=box]; + exit -> cadet; + exit -> tun; + exit -> dnsstub; + vpn -> cadet; + vpn -> regex; + vpn -> tun; + pt [shape=house]; + pt -> cadet; + pt -> vpn; + pt -> dns; + pt -> dnsparser; + dns -> tun; + dns -> dnsstub; + zonemaster [shape=house]; + zonemaster -> namestore; + zonemaster -> dht; + gns -> dns; + gns -> dht; + gns -> block [style=dotted,color=blue]; + gns -> revocation; + gns -> vpn; + gns -> dnsparser; + gns -> dnsstub; + gns -> identity; + revocation -> core; + revocation -> setu; + namestore -> identity; + namestore -> gnsrecord; + dnsparser -> gnsrecord [style=dotted,color=blue]; + conversation -> gnsrecord [style=dotted,color=blue]; + gns -> gnsrecord; + dht -> core; + dht -> nse; + dht -> block; + dht -> datacache; + dht -> peerinfo; + dht -> hello; + nse -> core; + regex -> block [style=dotted,color=blue]; + block [shape=diamond]; + datacache [shape=diamond]; + cadet -> core [weight=2]; + cadet -> dht; + cadet -> block [style=dotted,color=blue]; + conversation [shape=house]; + conversation -> cadet; + conversation -> gns; + conversation -> speaker; + conversation -> microphone; + speaker [shape=diamond]; + microphone [shape=diamond]; + regex -> dht; + core -> transport; + topology [shape=box]; + topology -> peerinfo; + topology -> transport; + topology -> core; + topology -> hello; + hostlist [shape=box]; + hostlist -> core; + hostlist -> peerinfo; + hostlist -> hello; + transport -> ats; + transport -> hello; + transport -> peerinfo; + transport -> nat; + transport -> fragmentation; + consensus -> set; + consensus -> cadet; + scalarproduct -> seti; + scalarproduct -> cadet; + set -> cadet; + seti -> cadet; + setu -> cadet; + peerinfo -> hello; + fragmentation [shape=diamond]; + hello [shape=diamond]; + nat [shape=diamond]; + tun [shape=diamond]; + dnsparser [shape=diamond]; + dnsstub [shape=diamond]; + + secushare [shape=house]; + multicast; + psyc; + social -> psyc; + social -> gns; + psyc -> psycstore; + psycstore; + social; + secushare -> social; + psyc -> multicast; + multicast -> cadet; + + rps; + rps -> core; +} diff --git a/_static/images/tng.dot b/_static/images/tng.dot @@ -0,0 +1,55 @@ +// house = application +// circle (default) = service +// box = daemon +// diamond = library +// black line = dependency +// blue line = extension via plugin +// red line = possibly useful +// dashed = in planning + +// this is what we have...o +digraph tng { + // splines = true; + compound=true; + subgraph cluster0 { + label="Our peer"; + style=dashed; + color=black; + subgraph cluster1 { + style=solid; + color=black; + tcp; + udp; + others [style=dotted]; + label="Communicators"; + } + subgraph cluster2 { + style=solid; + color=black; + dht; + fs; + cadet; + label="Applications"; + } + cadet -> core [ltail=cluster2,label="Communicate with peers"]; + dht -> transport [ltail=cluster2,label="Suggest connection to peer"]; + core -> transport [label="Send/receive messages via secure channel"]; + transport -> tcp [lhead=cluster1,dir=both,label="Offer connectivity/channel to other peer"]; + udp -> nat [label="Get addresses"]; + tcp -> nat; + } + subgraph cluster3 { + rank = sink; + style=dashed; + color=black; + peer3; + peer1; + peer2; + label="Other peers"; + } + + + tcp -> peer1 [dir=both]; + udp -> peer2; + transport->peer1 [style=invis]; +} diff --git a/_static/images/tng.png b/_static/images/tng.png Binary files differ. diff --git a/conf.py b/conf.py @@ -29,6 +29,7 @@ author = 'GNUnet Project' # ones. extensions = [ 'myst_parser', + 'sphinx.ext.todo', 'sphinx_rtd_theme' ] diff --git a/index.md b/index.md @@ -9,5 +9,5 @@ installing user configuration contributors -developer +man_developers/index.md ``` diff --git a/man_developers/contributing.rst b/man_developers/contributing.rst @@ -0,0 +1,110 @@ +.. _GNUnet-Contributors-Handbook: + +**************************** +GNUnet Contributors Handbook +**************************** + +.. _Contributing-to-GNUnet: + +Contributing to GNUnet +====================== + +.. _Licenses-of-contributions: + +:index:`Licenses of contributions <single: licenses; of contributions>` +======================================================================= + +GNUnet is a `GNU <https://www.gnu.org/>`__ package. All code +contributions must thus be put under the `GNU Affero Public License +(AGPL) <https://www.gnu.org/licenses/agpl.html>`__. All documentation +should be put under FSF approved licenses (see +`fdl <https://www.gnu.org/copyleft/fdl.html>`__). + +By submitting documentation, translations, and other content to GNUnet +you automatically grant the right to publish code under the GNU Public +License and documentation under either or both the GNU Public License or +the GNU Free Documentation License. When contributing to the GNUnet +project, GNU standards and the `GNU +philosophy <https://www.gnu.org/philosophy/philosophy.html>`__ should be +adhered to. + +.. _Copyright-Assignment: + +:index:`Copyright Assignment <single: copyright; assignment>` +============================================================= + +.. todo:: Link to copyright assignment. + +We require a formal copyright assignment for GNUnet contributors to +GNUnet e.V.; nevertheless, we do allow pseudonymous contributions. By +signing the copyright agreement and submitting your code (or +documentation) to us, you agree to share the rights to your code with +GNUnet e.V.; GNUnet e.V. receives non-exclusive ownership rights, and in +particular is allowed to dual-license the code. You retain non-exclusive +rights to your contributions, so you can also share your contributions +freely with other projects. + +GNUnet e.V. will publish all accepted contributions under the AGPLv3 or +any later version. The association may decide to publish contributions +under additional licenses (dual-licensing). + +We do not intentionally remove your name from your contributions; +however, due to extensive editing it is not always trivial to attribute +contributors properly. If you find that you significantly contributed to +a file (or the project as a whole) and are not listed in the respective +authors file or section, please do let us know. + +.. _Contributing-to-the-Reference-Manual: + +Contributing to the Reference Manual +==================================== + +.. todo:: Move section to contrib.rst? + +.. todo:: Update contrib section to reflect move to reStructuredText + +- When writing documentation, please use `gender-neutral + wording <https://en.wikipedia.org/wiki/Singular_they>`__ when + referring to people, such as singular "they", "their", "them", and so + forth. + +- Keep line length below 74 characters, except for URLs. URLs break in + the PDF output when they contain linebreaks. + +- Do not use tab characters (see chapter 2.1 texinfo manual) + +- Write texts in the third person perspective. + +.. _Contributing-testcases: + +Contributing testcases +====================== + +In the core of GNUnet, we restrict new testcases to a small subset of +languages, in order of preference: + +1. C + +2. Portable Shell Scripts + +3. Python (3.7 or later) + +We welcome efforts to remove our existing Python 2.7 scripts to replace +them either with portable shell scripts or, at your choice, Python 3.7 +or later. + +If you contribute new python based testcases, we advise you to not +repeat our past misfortunes and write the tests in a standard test +framework like for example pytest. + +For writing portable shell scripts, these tools are useful: + +* `Shellcheck <https://github.com/koalaman/shellcheck>`__, for static + analysis of shell scripts. +* http://www.etalabs.net/sh_tricks.html, +* ``bash``-``dash`` (``/bin/sh`` on Debian) interoperability + * `checkbashisms <https://salsa.debian.org/debian/devscripts/blob/master/scripts/checkbashisms.pl>`__, + * `https://wiki.ubuntu.com/DashAsBinSh`__, and + * `https://mywiki.wooledge.org/Bashism`__ + + diff --git a/man_developers/index.rst b/man_developers/index.rst @@ -0,0 +1,49 @@ + +.. _GNUnet-Developer-Handbook: + +######################### +GNUnet Developer Handbook +######################### + +This book is intended to be an introduction for programmers that want to +extend the GNUnet framework. GNUnet is more than a simple peer-to-peer +application. + +For developers, GNUnet is: + +* developed by a community that believes in the GNU philosophy +* Free Software (Free as in Freedom), licensed under the + `GNU Affero General Public License`_ +* A set of standards, including coding conventions and architectural rules +* A set of layered protocols, both specifying the communication + between peers as well as the communication between components + of a single peer +* A set of libraries with well-defined APIs suitable for + writing extensions + +In particular, the architecture specifies that a peer consists of many +processes communicating via protocols. Processes can be written in almost +any language. +``C``, ``Java`` and ``Guile`` APIs exist for accessing existing +services and for writing extensions. +It is possible to write extensions in other languages by +implementing the necessary IPC protocols. + +GNUnet can be extended and improved along many possible dimensions, and +anyone interested in Free Software and Freedom-enhancing Networking is +welcome to join the effort. This Developer Handbook attempts to provide +an initial introduction to some of the key design choices and central +components of the system. + +This part of the GNUnet documentation is far from complete, +and we welcome informed contributions, be it in the form of +new chapters, sections or insightful comments. + +.. toctree:: + contributing.rst + style.rst + + util/index.rst + subsystems/index.rst + +.. _GNU Affero General Public License: https://www.gnu.org/licenses/licenses.html#AGPL diff --git a/man_developers/repo.rst b/man_developers/repo.rst @@ -0,0 +1,260 @@ +******************** +Repository Structure +******************** + +.. _Code-overview: + +``src`` Overview +---------------- +.. to ../repo.rst + +This section gives a brief overview of the GNUnet source code. +Specifically, we sketch the function of each of the subdirectories in +the ``gnunet/src/`` directory. The order given is roughly bottom-up (in +terms of the layers of the system). + +.. todo:: Reorganise this list + +``util/`` --- libgnunetutil + Library with general utility functions, all GNUnet binaries link + against this library. Anything from memory allocation and data + structures to cryptography and inter-process communication. The goal + is to provide an OS-independent interface and more 'secure' or + convenient implementations of commonly used primitives. The API is + spread over more than a dozen headers, developers should study those + closely to avoid duplicating existing functions. see + `libgnunetutil <#libgnunetutil>`__. + +``hello/`` --- libgnunethello + HELLO messages are used to describe under which addresses a peer can + be reached (for example, protocol, IP, port). This library manages + parsing and generating of HELLO messages. + +``block/`` --- libgnunetblock + The DHT and other components of GNUnet store information in units + called 'blocks'. Each block has a type and the type defines a + particular format and how that binary format is to be linked to a + hash code (the key for the DHT and for databases). The block library + is a wrapper around block plugins which provide the necessary + functions for each block type. + +``statistics/`` --- statistics service + The statistics service enables associating values (of type uint64_t) + with a component name and a string. The main uses is debugging + (counting events), performance tracking and user entertainment (what + did my peer do today?). + +``arm/`` --- Automatic Restart Manager (ARM) + The automatic-restart-manager (ARM) service is the GNUnet master + service. Its role is to start gnunet-services, to re-start them when + they crashed and finally to shut down the system when requested. + +``peerinfo/`` --- peerinfo service + The peerinfo service keeps track of which peers are known to the + local peer and also tracks the validated addresses for each peer (in + the form of a HELLO message) for each of those peers. The peer is not + necessarily connected to all peers known to the peerinfo service. + Peerinfo provides persistent storage for peer identities --- peers + are not forgotten just because of a system restart. + +``datacache/`` --- libgnunetdatacache + The datacache library provides (temporary) block storage for the DHT. + Existing plugins can store blocks in Sqlite, Postgres or MySQL + databases. All data stored in the cache is lost when the peer is + stopped or restarted (datacache uses temporary tables). + +``datastore/`` --- datastore service + The datastore service stores file-sharing blocks in databases for + extended periods of time. In contrast to the datacache, data is not + lost when peers restart. However, quota restrictions may still cause + old, expired or low-priority data to be eventually discarded. + Existing plugins can store blocks in Sqlite, Postgres or MySQL + databases. + +``template/`` --- service template + Template for writing a new service. Does nothing. + +``ats/`` --- Automatic Transport Selection + The automatic transport selection (ATS) service is responsible for + deciding which address (i.e. which transport plugin) should be used + for communication with other peers, and at what bandwidth. + +``nat/`` --- libgnunetnat + Library that provides basic functions for NAT traversal. The library + supports NAT traversal with manual hole-punching by the user, UPnP + and ICMP-based autonomous NAT traversal. The library also includes an + API for testing if the current configuration works and the + ``gnunet-nat-server`` which provides an external service to test the + local configuration. + +``fragmentation/`` --- libgnunetfragmentation + Some transports (UDP and WLAN, mostly) have restrictions on the + maximum transfer unit (MTU) for packets. The fragmentation library + can be used to break larger packets into chunks of at most 1k and + transmit the resulting fragments reliably (with acknowledgment, + retransmission, timeouts, etc.). + +``transport/`` --- transport service + The transport service is responsible for managing the basic P2P + communication. It uses plugins to support P2P communication over TCP, + UDP, HTTP, HTTPS and other protocols. The transport service validates + peer addresses, enforces bandwidth restrictions, limits the total + number of connections and enforces connectivity restrictions (e.g. + friends-only). + +``peerinfo-tool/`` --- gnunet-peerinfo + This directory contains the gnunet-peerinfo binary which can be used + to inspect the peers and HELLOs known to the peerinfo service. + +``core/`` + The core service is responsible for establishing encrypted, + authenticated connections with other peers, encrypting and decrypting + messages and forwarding messages to higher-level services that are + interested in them. + +``testing/`` --- libgnunettesting + The testing library allows starting (and stopping) peers for writing + testcases. It also supports automatic generation of configurations + for peers ensuring that the ports and paths are disjoint. + libgnunettesting is also the foundation for the testbed service + +``testbed/`` --- testbed service + The testbed service is used for creating small or large scale + deployments of GNUnet peers for evaluation of protocols. It + facilitates peer deployments on multiple hosts (for example, in a + cluster) and establishing various network topologies (both underlay + and overlay). + +``nse/`` --- Network Size Estimation + The network size estimation (NSE) service implements a protocol for + (securely) estimating the current size of the P2P network. + +``dht/`` --- distributed hash table + The distributed hash table (DHT) service provides a distributed + implementation of a hash table to store blocks under hash keys in the + P2P network. + +``hostlist/`` --- hostlist service + The hostlist service allows learning about other peers in the network + by downloading HELLO messages from an HTTP server, can be configured + to run such an HTTP server and also implements a P2P protocol to + advertise and automatically learn about other peers that offer a + public hostlist server. + +``topology/`` --- topology service + The topology service is responsible for maintaining the mesh + topology. It tries to maintain connections to friends (depending on + the configuration) and also tries to ensure that the peer has a + decent number of active connections at all times. If necessary, new + connections are added. All peers should run the topology service, + otherwise they may end up not being connected to any other peer + (unless some other service ensures that core establishes the required + connections). The topology service also tells the transport service + which connections are permitted (for friend-to-friend networking) + +``fs/`` --- file-sharing + The file-sharing (FS) service implements GNUnet's file-sharing + application. Both anonymous file-sharing (using gap) and + non-anonymous file-sharing (using dht) are supported. + +``cadet/`` --- cadet service + The CADET service provides a general-purpose routing abstraction to + create end-to-end encrypted tunnels in mesh networks. We wrote a + paper documenting key aspects of the design. + +``tun/`` --- libgnunettun + Library for building IPv4, IPv6 packets and creating checksums for + UDP, TCP and ICMP packets. The header defines C structs for common + Internet packet formats and in particular structs for interacting + with TUN (virtual network) interfaces. + +``mysql/`` --- libgnunetmysql + Library for creating and executing prepared MySQL statements and to + manage the connection to the MySQL database. Essentially a + lightweight wrapper for the interaction between GNUnet components and + libmysqlclient. + +``dns/`` + Service that allows intercepting and modifying DNS requests of the + local machine. Currently used for IPv4-IPv6 protocol translation + (DNS-ALG) as implemented by \"pt/\" and for the GNUnet naming system. + The service can also be configured to offer an exit service for DNS + traffic. + +``vpn/`` --- VPN service + The virtual public network (VPN) service provides a virtual tunnel + interface (VTUN) for IP routing over GNUnet. Needs some other peers + to run an \"exit\" service to work. Can be activated using the + \"gnunet-vpn\" tool or integrated with DNS using the \"pt\" daemon. + +``exit/`` + Daemon to allow traffic from the VPN to exit this peer to the + Internet or to specific IP-based services of the local peer. + Currently, an exit service can only be restricted to IPv4 or IPv6, + not to specific ports and or IP address ranges. If this is not + acceptable, additional firewall rules must be added manually. exit + currently only works for normal UDP, TCP and ICMP traffic; DNS + queries need to leave the system via a DNS service. + +``pt/`` + protocol translation daemon. This daemon enables 4-to-6, 6-to-4, + 4-over-6 or 6-over-4 transitions for the local system. It essentially + uses \"DNS\" to intercept DNS replies and then maps results to those + offered by the VPN, which then sends them using mesh to some daemon + offering an appropriate exit service. + +``identity/`` + Management of egos (alter egos) of a user; identities are essentially + named ECC private keys and used for zones in the GNU name system and + for namespaces in file-sharing, but might find other uses later + +``revocation/`` + Key revocation service, can be used to revoke the private key of an + identity if it has been compromised + +``namecache/`` + Cache for resolution results for the GNU name system; data is + encrypted and can be shared among users, loss of the data should + ideally only result in a performance degradation (persistence not + required) + +``namestore/`` + Database for the GNU name system with per-user private information, + persistence required + +``gns/`` + GNU name system, a GNU approach to DNS and PKI. + +``dv/`` + A plugin for distance-vector (DV)-based routing. DV consists of a + service and a transport plugin to provide peers with the illusion of + a direct P2P connection for connections that use multiple (typically + up to 3) hops in the actual underlay network. + +``regex/`` + Service for the (distributed) evaluation of regular expressions. + +``scalarproduct/`` + The scalar product service offers an API to perform a secure + multiparty computation which calculates a scalar product between two + peers without exposing the private input vectors of the peers to each + other. + +``consensus/`` + The consensus service will allow a set of peers to agree on a set of + values via a distributed set union computation. + +``reclaim/`` + A decentralized personal data sharing service used to realize a + decentralized identity provider. Supports OpenID Connect. See also + https://reclaim.gnunet.org. + +``rest/`` + The rest API allows access to GNUnet services using RESTful + interaction. The services provide plugins that can exposed by the + rest server. + +.. FIXME: Where did this disappear to? +.. ``experimentation/`` + The experimentation daemon coordinates distributed experimentation + to evaluate transport and ATS properties. diff --git a/man_developers/style.rst b/man_developers/style.rst @@ -0,0 +1,152 @@ + +****************** +GNUnet Style Guide +****************** + +This document contains normative rules for writing GNUnet +code and naming conventions used throughout the project. + + +Naming conventions +================== + +Header files +------------ +.. Not sure if "include" and "header" files are synonymous. + + +For header files, the following suffixes should be used: + +============= ====================================== +Suffix Usage +============= ====================================== +``_lib`` Libraries without associated processes +``_service`` Libraries using service processes +``_plugin`` Plugin definition +``_protocol`` structs used in network protocol +============= ====================================== + +There exist a few exceptions to these rules within the codebase: + +* ``gnunet_config.h`` and ``gnunet_directories.h`` are automatically + generated. +* ``gnunet_common.h``, which defines fundamental routines +* ``platform.h``, first included. + .. I have no idea what that means +* ``gettext.h``, an external library. + + +Binaries +-------- + +For binary files, the following convention should be used: + +=============================== ========================================= +Name format Usage +=============================== ========================================= +``gnunet-service-xxx`` Service processes (with listen sockets) +``gnunet-daemon-xxx`` Daemon processes (without listen sockets) +``gnunet-helper-xxx[-yyy]`` SUID helper for module xxx +``gnunet-yyy`` End-user command line tools +``libgnunet_plugin_xxx_yyy.so`` Plugin for API xxx +``libgnunetxxx.so`` Library for API xxx +=============================== ========================================= + +Logging +------- + +The convention is to define a macro on a per-file basis to manage logging: + +.. code-block:: c + + #define LOG(kind,...) + [logging_macro] (kind, "[component_name]", __VA_ARGS__) + +The table below indicates the substitutions which should be made +for ``[component_name]`` and ``[logging_macro]``. + +======================== ========================================= =================== +Software category ``[component_name]`` ``[logging_macro]`` +======================== ========================================= =================== +Services and daemons Directory name in ``GNUNET_log_setup`` ``GNUNET_log`` +Command line tools Full name in ``GNUNET_log_setup`` ``GNUNET_log`` +Service access libraries ``[directory_name]`` ``GNUNET_log_from`` +Pure libraries Library name (without ``lib`` or ``.so``) ``GNUNET_log_from`` +Plugins ``[directory_name]-[plugin_name]`` ``GNUNET_log_from`` +======================== ========================================= =================== + +.. todo:: Clear up terminology within the style guide (_lib, _service mapped to appropriate software categories) + +.. todo:: Interpret and write configuration style + +Symbols +------- + +Exported symbols must be prefixed with ``GNUNET_[module_name]_`` and be +defined in ``[module_name].c``. The only exceptions to this rule are +symbols defined in ``gnunet_common.h``. + +Private symbols, including ``struct``\ s and macros, must not be prefixed. +In addition, they must not be exported in a way that linkers could use them +or other libraries might see them via headers. This means that they must +**never** be declared in ``src/include``, and only declared or defined in +C source files or headers under ``src/[module_name]``. + + +Tests +----- + +Test cases and performance tests should follow the naming conventions +``test_[module-under-test]_[test_description].c`` and +``perf_[module-under-test]_[test_description].c``, respectively. + +In either case, if there is only a single test, ``[test_description]`` +may be omitted. + + +``src`` subdirectories +---------------------- + +Subdirectories of ``src`` + + + +Coding style +============ +.. todo:: Examples should follow GNU Coding Standards? + +This project follows the GNU Coding Standards. + +Indentation is done with two spaces per level, never with tabs. +Specific (though incomplete) indentation rules are defined in an ``uncrustify`` +configuration file (in ``contrib``) and are enforced by Git hooks. + +.. todo:: Link to uncrustify config in contrib. + +C99-style struct initialisation is acceptable and generally encouraged. + +.. todo:: Clarify whether there are cases where C99-style struct init is discouraged? + +As in all good C code, we care about symbol space pollution and thus use +:code:`static` to limit the scope where possible, even in the compilation +unit that contains :code:`main`. + +Only one variable should be declared per line: + +.. code-block:: c + + // bad + int i,j; + + // good + int i; + int j; + +This helps keep diffs small and forces developers to think precisely about +the type of every variable. + +Note that :c:`char *` is different from :c:`const char*` and +:c:`int` is different from :c:`unsigned int` or :c:`uint32_t`. +Each variable type should be chosen with care. + +.. code-block:: c diff --git a/man_developers/subsystems/apps.rst b/man_developers/subsystems/apps.rst @@ -0,0 +1,9 @@ +Applications +============ + +.. toctree:: + fs/fs.rst + identity/identity.rst + revocation/revocation.rst + messenger/messenger.rst + rest/rest.rst diff --git a/man_developers/subsystems/ats/ats.rst b/man_developers/subsystems/ats/ats.rst @@ -0,0 +1,27 @@ +.. index:: + double: subsystem; Automatic transport selection + +.. _ATS-Subsystem: + +ATS — Automatic transport selection +=================================== + +ATS stands for \"automatic transport selection\", and the function of +ATS in GNUnet is to decide on which address (and thus transport plugin) +should be used for two peers to communicate, and what bandwidth limits +should be imposed on such an individual connection. + +To help ATS make an informed decision, higher-level services inform the +ATS service about their requirements and the quality of the service +rendered. The ATS service also interacts with the transport service to +be appraised of working addresses and to communicate its resource allocation +decisions. Finally, the ATS service's operation can be observed using a +monitoring API. + +The main logic of the ATS service only collects the available addresses, +their performance characteristics and the applications requirements, but +does not make the actual allocation decision. This last critical step is +left to an ATS plugin, as we have implemented (currently three) +different allocation strategies which differ significantly in their +performance and maturity, and it is still unclear if any particular +plugin is generally superior. diff --git a/man_developers/subsystems/cadet/cadet.rst b/man_developers/subsystems/cadet/cadet.rst @@ -0,0 +1,150 @@ + +.. _CADET-Subsystem: + +.. index:: + double: CADET; subsystem + +CADET — Confidential Ad-hoc Decentralized End-to-end Transport +============================================================== + +The CADET subsystem in GNUnet is responsible for secure end-to-end +communications between nodes in the GNUnet overlay network. CADET builds +on the CORE subsystem, which provides for the link-layer communication, +by adding routing, forwarding, and additional security to the +connections. CADET offers the same cryptographic services as CORE, but +on an end-to-end level. This is done so peers retransmitting traffic on +behalf of other peers cannot access the payload data. + +- CADET provides confidentiality with so-called perfect forward + secrecy; we use ECDHE powered by Curve25519 for the key exchange and + then use symmetric encryption, encrypting with both AES-256 and + Twofish + +- authentication is achieved by signing the ephemeral keys using + Ed25519, a deterministic variant of ECDSA + +- integrity protection (using SHA-512 to do encrypt-then-MAC, although + only 256 bits are sent to reduce overhead) + +- replay protection (using nonces, timestamps, challenge-response, + message counters and ephemeral keys) + +- liveness (keep-alive messages, timeout) + +Additional to the CORE-like security benefits, CADET offers other +properties that make it a more universal service than CORE. + +- CADET can establish channels to arbitrary peers in GNUnet. If a peer + is not immediately reachable, CADET will find a path through the + network and ask other peers to retransmit the traffic on its behalf. + +- CADET offers (optional) reliability mechanisms. In a reliable channel + traffic is guaranteed to arrive complete, unchanged and in-order. + +- CADET takes care of flow and congestion control mechanisms, not + allowing the sender to send more traffic than the receiver or the + network are able to process. + +:index:`libgnunetcadet <single: libgnunet; cadet>` +-------------------------------------------------- + +The CADET API (defined in ``gnunet_cadet_service.h``) is the messaging +API used by P2P applications built using GNUnet. It provides +applications the ability to send and receive encrypted messages to any +peer participating in GNUnet. The API is heavily based on the CORE API. + +CADET delivers messages to other peers in \"channels\". A channel is a +permanent connection defined by a destination peer (identified by its +public key) and a port number. Internally, CADET tunnels all channels +towards a destination peer using one session key and relays the data on +multiple \"connections\", independent from the channels. + +Each channel has optional parameters, the most important being the +reliability flag. Should a message get lost on TRANSPORT/CORE level, if +a channel is created with as reliable, CADET will retransmit the lost +message and deliver it in order to the destination application. + +GNUNET_CADET_connect + +.. .. doxygenfunction:: GNUNET_CADET_connect + +To communicate with other peers using CADET, it is necessary to first +connect to the service using ``GNUNET_CADET_connect``. This function +takes several parameters in form of callbacks, to allow the client to +react to various events, like incoming channels or channels that +terminate, as well as specify a list of ports the client wishes to +listen to (at the moment it is not possible to start listening on +further ports once connected, but nothing prevents a client to connect +several times to CADET, even do one connection per listening port). The +function returns a handle which has to be used for any further +interaction with the service. + +GNUNET_CADET_channel_create + +.. .. doxygenfunction:: GNUNET_CADET_channel_create + +To connect to a remote peer, a client has to call the +``GNUNET_CADET_channel_create`` function. The most important parameters +given are the remote peer's identity (it public key) and a port, which +specifies which application on the remote peer to connect to, similar to +TCP/UDP ports. CADET will then find the peer in the GNUnet network and +establish the proper low-level connections and do the necessary key +exchanges to assure and authenticated, secure and verified +communication. Similar to +``GNUNET_CADET_connect``,\ ``GNUNET_CADET_create_channel`` returns a +handle to interact with the created channel. + +GNUNET_CADET_notify_transmit_ready + +.. .. doxygenfunction:: GNUNET_CADET_notify_transmit_ready + +For every message the client wants to send to the remote application, +``GNUNET_CADET_notify_transmit_ready`` must be called, indicating the +channel on which the message should be sent and the size of the message +(but not the message itself!). Once CADET is ready to send the message, +the provided callback will fire, and the message contents are provided +to this callback. + +Please note the CADET does not provide an explicit notification of when +a channel is connected. In loosely connected networks, like big wireless +mesh networks, this can take several seconds, even minutes in the worst +case. To be alerted when a channel is online, a client can call +``GNUNET_CADET_notify_transmit_ready`` immediately after +``GNUNET_CADET_create_channel``. When the callback is activated, it +means that the channel is online. The callback can give 0 bytes to CADET +if no message is to be sent, this is OK. + +GNUNET_CADET_notify_transmit_cancel + +.. .. doxygenfunction:: GNUNET_CADET_notify_transmit_cancel + +If a transmission was requested but before the callback fires it is no +longer needed, it can be canceled with +``GNUNET_CADET_notify_transmit_ready_cancel``, which uses the handle +given back by ``GNUNET_CADET_notify_transmit_ready``. As in the case of +CORE, only one message can be requested at a time: a client must not +call ``GNUNET_CADET_notify_transmit_ready`` again until the callback is +called or the request is canceled. + +GNUNET_CADET_channel_destroy + +.. .. doxygenfunction:: GNUNET_CADET_notify_channel_destroy + +When a channel is no longer needed, a client can call +``GNUNET_CADET_channel_destroy`` to get rid of it. Note that CADET will +try to transmit all pending traffic before notifying the remote peer of +the destruction of the channel, including retransmitting lost messages +if the channel was reliable. + +Incoming channels, channels being closed by the remote peer, and traffic +on any incoming or outgoing channels are given to the client when CADET +executes the callbacks given to it at the time of +``GNUNET_CADET_connect``. + +GNUNET_CADET_disconnect + +.. .. doxygenfunction:: GNUNET_CADET_disconnect + +Finally, when an application no longer wants to use CADET, it should +call ``GNUNET_CADET_disconnect``, but first all channels and pending +transmissions must be closed (otherwise CADET will complain). diff --git a/man_developers/subsystems/core/core.rst b/man_developers/subsystems/core/core.rst @@ -0,0 +1,385 @@ +.. _CORE-Subsystem: + +.. index:: + double: CORE; subsystem + +CORE — GNUnet link layer +======================== + +The CORE subsystem in GNUnet is responsible for securing link-layer +communications between nodes in the GNUnet overlay network. CORE builds +on the TRANSPORT subsystem which provides for the actual, insecure, +unreliable link-layer communication (for example, via UDP or WLAN), and +then adds fundamental security to the connections: + +- confidentiality with so-called perfect forward secrecy; we use ECDHE + (`Elliptic-curve + Diffie—Hellman <http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman>`__) + powered by Curve25519 (`Curve25519 <http://cr.yp.to/ecdh.html>`__) + for the key exchange and then use symmetric encryption, encrypting + with both AES-256 + (`AES-256 <http://en.wikipedia.org/wiki/Rijndael>`__) and Twofish + (`Twofish <http://en.wikipedia.org/wiki/Twofish>`__) + +- `authentication <http://en.wikipedia.org/wiki/Authentication>`__ is + achieved by signing the ephemeral keys using Ed25519 + (`Ed25519 <http://ed25519.cr.yp.to/>`__), a deterministic variant of + ECDSA (`ECDSA <http://en.wikipedia.org/wiki/ECDSA>`__) + +- integrity protection (using SHA-512 + (`SHA-512 <http://en.wikipedia.org/wiki/SHA-2>`__) to do + encrypt-then-MAC + (`encrypt-then-MAC <http://en.wikipedia.org/wiki/Authenticated_encryption>`__)) + +- Replay (`replay <http://en.wikipedia.org/wiki/Replay_attack>`__) + protection (using nonces, timestamps, challenge-response, message + counters and ephemeral keys) + +- liveness (keep-alive messages, timeout) + +.. _Limitations: + +:index:`Limitations <CORE; limitations>` +---------------------------------------- + +CORE does not perform +`routing <http://en.wikipedia.org/wiki/Routing>`__; using CORE it is +only possible to communicate with peers that happen to already be +\"directly\" connected with each other. CORE also does not have an API +to allow applications to establish such \"direct\" connections --- for +this, applications can ask TRANSPORT, but TRANSPORT might not be able to +establish a \"direct\" connection. The TOPOLOGY subsystem is responsible +for trying to keep a few \"direct\" connections open at all times. +Applications that need to talk to particular peers should use the CADET +subsystem, as it can establish arbitrary \"indirect\" connections. + +Because CORE does not perform routing, CORE must only be used directly +by applications that either perform their own routing logic (such as +anonymous file-sharing) or that do not require routing, for example +because they are based on flooding the network. CORE communication is +unreliable and delivery is possibly out-of-order. Applications that +require reliable communication should use the CADET service. Each +application can only queue one message per target peer with the CORE +service at any time; messages cannot be larger than approximately 63 +kilobytes. If messages are small, CORE may group multiple messages +(possibly from different applications) prior to encryption. If permitted +by the application (using the `cork <http://baus.net/on-tcp_cork/>`__ +option), CORE may delay transmissions to facilitate grouping of multiple +small messages. If cork is not enabled, CORE will transmit the message +as soon as TRANSPORT allows it (TRANSPORT is responsible for limiting +bandwidth and congestion control). CORE does not allow flow control; +applications are expected to process messages at line-speed. If flow +control is needed, applications should use the CADET service. + +.. when is a peer connected +.. _When-is-a-peer-_0022connected_0022_003f: + +When is a peer \"connected\"? +----------------------------- + +In addition to the security features mentioned above, CORE also provides +one additional key feature to applications using it, and that is a +limited form of protocol-compatibility checking. CORE distinguishes +between TRANSPORT-level connections (which enable communication with +other peers) and application-level connections. Applications using the +CORE API will (typically) learn about application-level connections from +CORE, and not about TRANSPORT-level connections. When a typical +application uses CORE, it will specify a set of message types (from +``gnunet_protocols.h``) that it understands. CORE will then notify the +application about connections it has with other peers if and only if +those applications registered an intersecting set of message types with +their CORE service. Thus, it is quite possible that CORE only exposes a +subset of the established direct connections to a particular application +--- and different applications running above CORE might see different +sets of connections at the same time. + +A special case are applications that do not register a handler for any +message type. CORE assumes that these applications merely want to +monitor connections (or \"all\" messages via other callbacks) and will +notify those applications about all connections. This is used, for +example, by the ``gnunet-core`` command-line tool to display the active +connections. Note that it is also possible that the TRANSPORT service +has more active connections than the CORE service, as the CORE service +first has to perform a key exchange with connecting peers before +exchanging information about supported message types and notifying +applications about the new connection. + + +:index:`libgnunetcore <libgnunet; core>` +---------------------------------------- + +The CORE API (defined in ``gnunet_core_service.h``) is the basic +messaging API used by P2P applications built using GNUnet. It provides +applications the ability to send and receive encrypted messages to the +peer's \"directly\" connected neighbours. + +As CORE connections are generally \"direct\" connections, applications +must not assume that they can connect to arbitrary peers this way, as +\"direct\" connections may not always be possible. Applications using +CORE are notified about which peers are connected. Creating new +\"direct\" connections must be done using the TRANSPORT API. + +The CORE API provides unreliable, out-of-order delivery. While the +implementation tries to ensure timely, in-order delivery, both message +losses and reordering are not detected and must be tolerated by the +application. Most important, the core will NOT perform retransmission if +messages could not be delivered. + +Note that CORE allows applications to queue one message per connected +peer. The rate at which each connection operates is influenced by the +preferences expressed by local application as well as restrictions +imposed by the other peer. Local applications can express their +preferences for particular connections using the \"performance\" API of +the ATS service. + +Applications that require more sophisticated transmission capabilities +such as TCP-like behavior, or if you intend to send messages to +arbitrary remote peers, should use the CADET API. + +The typical use of the CORE API is to connect to the CORE service using +``GNUNET_CORE_connect``, process events from the CORE service (such as +peers connecting, peers disconnecting and incoming messages) and send +messages to connected peers using ``GNUNET_CORE_notify_transmit_ready``. +Note that applications must cancel pending transmission requests if they +receive a disconnect event for a peer that had a transmission pending; +furthermore, queuing more than one transmission request per peer per +application using the service is not permitted. + +The CORE API also allows applications to monitor all communications of +the peer prior to encryption (for outgoing messages) or after decryption +(for incoming messages). This can be useful for debugging, diagnostics +or to establish the presence of cover traffic (for anonymity). As +monitoring applications are often not interested in the payload, the +monitoring callbacks can be configured to only provide the message +headers (including the message type and size) instead of copying the +full data stream to the monitoring client. + +The init callback of the ``GNUNET_CORE_connect`` function is called with +the hash of the public key of the peer. This public key is used to +identify the peer globally in the GNUnet network. Applications are +encouraged to check that the provided hash matches the hash that they +are using (as theoretically the application may be using a different +configuration file with a different private key, which would result in +hard to find bugs). + +As with most service APIs, the CORE API isolates applications from +crashes of the CORE service. If the CORE service crashes, the +application will see disconnect events for all existing connections. +Once the connections are re-established, the applications will be +receive matching connect events. + +core client-service protocol +.. _The-CORE-Client_002dService-Protocol: + +The CORE Client-Service Protocol +-------------------------------- + +This section describes the protocol between an application using the +CORE service (the client) and the CORE service process itself. + +.. _Setup2: + +Setup2 +^^^^^^ + +When a client connects to the CORE service, it first sends a +``InitMessage`` which specifies options for the connection and a set of +message type values which are supported by the application. The options +bitmask specifies which events the client would like to be notified +about. The options include: + +**GNUNET_CORE_OPTION_NOTHING** + No notifications + +**GNUNET_CORE_OPTION_STATUS_CHANGE** + Peers connecting and disconnecting + +**GNUNET_CORE_OPTION_FULL_INBOUND** + All inbound messages (after decryption) with full payload + +**GNUNET_CORE_OPTION_HDR_INBOUND** + Just the ``MessageHeader`` of all inbound messages + +**GNUNET_CORE_OPTION_FULL_OUTBOUND** + All outbound messages (prior to encryption) with full payload + +**GNUNET_CORE_OPTION_HDR_OUTBOUND** + Just the ``MessageHeader`` of all outbound messages + +Typical applications will only monitor for connection status changes. + +The CORE service responds to the ``InitMessage`` with an +``InitReplyMessage`` which contains the peer's identity. Afterwards, +both CORE and the client can send messages. + +.. _Notifications: + +Notifications +^^^^^^^^^^^^^ + +The CORE will send ``ConnectNotifyMessage``\ s and +``DisconnectNotifyMessage``\ s whenever peers connect or disconnect from +the CORE (assuming their type maps overlap with the message types +registered by the client). When the CORE receives a message that matches +the set of message types specified during the ``InitMessage`` (or if +monitoring is enabled in for inbound messages in the options), it sends +a ``NotifyTrafficMessage`` with the peer identity of the sender and the +decrypted payload. The same message format (except with +``GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND`` for the message type) is +used to notify clients monitoring outbound messages; here, the peer +identity given is that of the receiver. + +.. _Sending: + +Sending +^^^^^^^ + +When a client wants to transmit a message, it first requests a +transmission slot by sending a ``SendMessageRequest`` which specifies +the priority, deadline and size of the message. Note that these values +may be ignored by CORE. When CORE is ready for the message, it answers +with a ``SendMessageReady`` response. The client can then transmit the +payload with a ``SendMessage`` message. Note that the actual message +size in the ``SendMessage`` is allowed to be smaller than the size in +the original request. A client may at any time send a fresh +``SendMessageRequest``, which then superceeds the previous +``SendMessageRequest``, which is then no longer valid. The client can +tell which ``SendMessageRequest`` the CORE service's +``SendMessageReady`` message is for as all of these messages contain a +\"unique\" request ID (based on a counter incremented by the client for +each request). + +CORE Peer-to-Peer Protocol +.. _The-CORE-Peer_002dto_002dPeer-Protocol: + +The CORE Peer-to-Peer Protocol +------------------------------ + +EphemeralKeyMessage creation +.. _Creating-the-EphemeralKeyMessage: + +Creating the EphemeralKeyMessage +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When the CORE service starts, each peer creates a fresh ephemeral (ECC) +public-private key pair and signs the corresponding +``EphemeralKeyMessage`` with its long-term key (which we usually call +the peer's identity; the hash of the public long term key is what +results in a ``struct GNUNET_PeerIdentity`` in all GNUnet APIs. The +ephemeral key is ONLY used for an ECDHE (`Elliptic-curve +Diffie---Hellman <http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman>`__) +exchange by the CORE service to establish symmetric session keys. A peer +will use the same ``EphemeralKeyMessage`` for all peers for +``REKEY_FREQUENCY``, which is usually 12 hours. After that time, it will +create a fresh ephemeral key (forgetting the old one) and broadcast the +new ``EphemeralKeyMessage`` to all connected peers, resulting in fresh +symmetric session keys. Note that peers independently decide on when to +discard ephemeral keys; it is not a protocol violation to discard keys +more often. Ephemeral keys are also never stored to disk; restarting a +peer will thus always create a fresh ephemeral key. The use of ephemeral +keys is what provides `forward +secrecy <http://en.wikipedia.org/wiki/Forward_secrecy>`__. + +Just before transmission, the ``EphemeralKeyMessage`` is patched to +reflect the current sender_status, which specifies the current state of +the connection from the point of view of the sender. The possible values +are: + +- ``KX_STATE_DOWN`` Initial value, never used on the network + +- ``KX_STATE_KEY_SENT`` We sent our ephemeral key, do not know the key + of the other peer + +- ``KX_STATE_KEY_RECEIVED`` This peer has received a valid ephemeral + key of the other peer, but we are waiting for the other peer to + confirm it's authenticity (ability to decode) via challenge-response. + +- ``KX_STATE_UP`` The connection is fully up from the point of view of + the sender (now performing keep-alive) + +- ``KX_STATE_REKEY_SENT`` The sender has initiated a rekeying + operation; the other peer has so far failed to confirm a working + connection using the new ephemeral key + +.. _Establishing-a-connection: + +Establishing a connection +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Peers begin their interaction by sending a ``EphemeralKeyMessage`` to +the other peer once the TRANSPORT service notifies the CORE service +about the connection. A peer receiving an ``EphemeralKeyMessage`` with a +status indicating that the sender does not have the receiver's ephemeral +key, the receiver's ``EphemeralKeyMessage`` is sent in response. +Additionally, if the receiver has not yet confirmed the authenticity of +the sender, it also sends an (encrypted)\ ``PingMessage`` with a +challenge (and the identity of the target) to the other peer. Peers +receiving a ``PingMessage`` respond with an (encrypted) ``PongMessage`` +which includes the challenge. Peers receiving a ``PongMessage`` check +the challenge, and if it matches set the connection to ``KX_STATE_UP``. + +.. _Encryption-and-Decryption: + +Encryption and Decryption +^^^^^^^^^^^^^^^^^^^^^^^^^ + +All functions related to the key exchange and encryption/decryption of +messages can be found in ``gnunet-service-core_kx.c`` (except for the +cryptographic primitives, which are in ``util/crypto*.c``). Given the +key material from ECDHE, a Key derivation function (`Key derivation +function <https://en.wikipedia.org/wiki/Key_derivation_function>`__) is +used to derive two pairs of encryption and decryption keys for AES-256 +and TwoFish, as well as initialization vectors and authentication keys +(for HMAC (`HMAC <https://en.wikipedia.org/wiki/HMAC>`__)). The HMAC is +computed over the encrypted payload. Encrypted messages include an +iv_seed and the HMAC in the header. + +Each encrypted message in the CORE service includes a sequence number +and a timestamp in the encrypted payload. The CORE service remembers the +largest observed sequence number and a bit-mask which represents which +of the previous 32 sequence numbers were already used. Messages with +sequence numbers lower than the largest observed sequence number minus +32 are discarded. Messages with a timestamp that is less than +``REKEY_TOLERANCE`` off (5 minutes) are also discarded. This of course +means that system clocks need to be reasonably synchronized for peers to +be able to communicate. Additionally, as the ephemeral key changes every +12 hours, a peer would not even be able to decrypt messages older than +12 hours. + +.. _Type-maps: + +Type maps +^^^^^^^^^ + +Once an encrypted connection has been established, peers begin to +exchange type maps. Type maps are used to allow the CORE service to +determine which (encrypted) connections should be shown to which +applications. A type map is an array of 65536 bits representing the +different types of messages understood by applications using the CORE +service. Each CORE service maintains this map, simply by setting the +respective bit for each message type supported by any of the +applications using the CORE service. Note that bits for message types +embedded in higher-level protocols (such as MESH) will not be included +in these type maps. + +Typically, the type map of a peer will be sparse. Thus, the CORE service +attempts to compress its type map using ``gzip``-style compression +(\"deflate\") prior to transmission. However, if the compression fails +to compact the map, the map may also be transmitted without compression +(resulting in ``GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP`` or +``GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP`` messages respectively). +Upon receiving a type map, the respective CORE service notifies +applications about the connection to the other peer if they support any +message type indicated in the type map (or no message type at all). If +the CORE service experience a connect or disconnect event from an +application, it updates its type map (setting or unsetting the +respective bits) and notifies its neighbours about the change. The CORE +services of the neighbours then in turn generate connect and disconnect +events for the peer that sent the type map for their respective +applications. As CORE messages may be lost, the CORE service confirms +receiving a type map by sending back a +``GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP``. If such a confirmation +(with the correct hash of the type map) is not received, the sender will +retransmit the type map (with exponential back-off). + + diff --git a/man_developers/subsystems/corestack.rst b/man_developers/subsystems/corestack.rst @@ -0,0 +1,23 @@ + +Basic Services +============== + +These services comprise a backbone of core services for +peer-to-peer applications to use. + +.. toctree:: + statistics/statistics.rst + ats/ats.rst + transport/transport.rst + transport-ng/transport-ng.rst + hostlist/hostlist.rst + peerinfo/peerinfo.rst + peerstore/peerstore.rst + core/core.rst + nse/nse.rst + dht/dht.rst + regex/regex.rst + cadet/cadet.rst + rps/rps.rst + + diff --git a/man_developers/subsystems/deps.rst b/man_developers/subsystems/deps.rst @@ -0,0 +1,100 @@ +.. _Internal-dependencies: + +Internal dependencies +===================== + +.. todo:: Break out into per-process information? + +This section tries to give an overview of what processes a typical +GNUnet peer running a particular application would consist of. All of +the processes listed here should be automatically started by +``gnunet-arm -s``. The list is given as a rough first guide to users for +failure diagnostics. Ideally, end-users should never have to worry about +these internal dependencies. + +In terms of internal dependencies, a minimum file-sharing system +consists of the following GNUnet processes (in order of dependency): + +- gnunet-service-arm + +- gnunet-service-resolver (required by all) + +- gnunet-service-statistics (required by all) + +- gnunet-service-peerinfo + +- gnunet-service-transport (requires peerinfo) + +- gnunet-service-core (requires transport) + +- gnunet-daemon-hostlist (requires core) + +- gnunet-daemon-topology (requires hostlist, peerinfo) + +- gnunet-service-datastore + +- gnunet-service-dht (requires core) + +- gnunet-service-identity + +- gnunet-service-fs (requires identity, mesh, dht, datastore, core) + +A minimum VPN system consists of the following GNUnet processes (in +order of dependency): + +- gnunet-service-arm + +- gnunet-service-resolver (required by all) + +- gnunet-service-statistics (required by all) + +- gnunet-service-peerinfo + +- gnunet-service-transport (requires peerinfo) + +- gnunet-service-core (requires transport) + +- gnunet-daemon-hostlist (requires core) + +- gnunet-service-dht (requires core) + +- gnunet-service-mesh (requires dht, core) + +- gnunet-service-dns (requires dht) + +- gnunet-service-regex (requires dht) + +- gnunet-service-vpn (requires regex, dns, mesh, dht) + +A minimum GNS system consists of the following GNUnet processes (in +order of dependency): + +- gnunet-service-arm + +- gnunet-service-resolver (required by all) + +- gnunet-service-statistics (required by all) + +- gnunet-service-peerinfo + +- gnunet-service-transport (requires peerinfo) + +- gnunet-service-core (requires transport) + +- gnunet-daemon-hostlist (requires core) + +- gnunet-service-dht (requires core) + +- gnunet-service-mesh (requires dht, core) + +- gnunet-service-dns (requires dht) + +- gnunet-service-regex (requires dht) + +- gnunet-service-vpn (requires regex, dns, mesh, dht) + +- gnunet-service-identity + +- gnunet-service-namestore (requires identity) + +- gnunet-service-gns (requires vpn, dns, dht, namestore, identity) diff --git a/man_developers/subsystems/dht/dht.rst b/man_developers/subsystems/dht/dht.rst @@ -0,0 +1,414 @@ +.. _Distributed-Hash-Table-_0028DHT_0029: + +.. index:: + double: Distributed hash table; subsystem + see: DHT; Distributed hash table + +DHT — Distributed Hash Table +============================ + +GNUnet includes a generic distributed hash table that can be used by +developers building P2P applications in the framework. This section +documents high-level features and how developers are expected to use the +DHT. We have a research paper detailing how the DHT works. Also, Nate's +thesis includes a detailed description and performance analysis (in +chapter 6). [R5N2011]_ + +.. todo:: Confirm: Are "Nate's thesis" and the "research paper" separate + entities? + +Key features of GNUnet's DHT include: + +- stores key-value pairs with values up to (approximately) 63k in size + +- works with many underlay network topologies (small-world, random + graph), underlay does not need to be a full mesh / clique + +- support for extended queries (more than just a simple 'key'), + filtering duplicate replies within the network (bloomfilter) and + content validation (for details, please read the subsection on the + block library) + +- can (optionally) return paths taken by the PUT and GET operations to + the application + +- provides content replication to handle churn + +GNUnet's DHT is randomized and unreliable. Unreliable means that there +is no strict guarantee that a value stored in the DHT is always found +— values are only found with high probability. While this is somewhat +true in all P2P DHTs, GNUnet developers should be particularly wary of +this fact (this will help you write secure, fault-tolerant code). Thus, +when writing any application using the DHT, you should always consider +the possibility that a value stored in the DHT by you or some other peer +might simply not be returned, or returned with a significant delay. Your +application logic must be written to tolerate this (naturally, some loss +of performance or quality of service is expected in this case). + +.. _Block-library-and-plugins: + +Block library and plugins +------------------------- + +.. _What-is-a-Block_003f: + +What is a Block? +^^^^^^^^^^^^^^^^ + +Blocks are small (< 63k) pieces of data stored under a key (struct +GNUNET_HashCode). Blocks have a type (enum GNUNET_BlockType) which +defines their data format. Blocks are used in GNUnet as units of static +data exchanged between peers and stored (or cached) locally. Uses of +blocks include file-sharing (the files are broken up into blocks), the +VPN (DNS information is stored in blocks) and the DHT (all information +in the DHT and meta-information for the maintenance of the DHT are both +stored using blocks). The block subsystem provides a few common +functions that must be available for any type of block. + +libgnunetblock API +.. _The-API-of-libgnunetblock: + +The API of libgnunetblock +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The block library requires for each (family of) block type(s) a block +plugin (implementing ``gnunet_block_plugin.h``) that provides basic +functions that are needed by the DHT (and possibly other subsystems) to +manage the block. These block plugins are typically implemented within +their respective subsystems. The main block library is then used to +locate, load and query the appropriate block plugin. Which plugin is +appropriate is determined by the block type (which is just a 32-bit +integer). Block plugins contain code that specifies which block types +are supported by a given plugin. The block library loads all block +plugins that are installed at the local peer and forwards the +application request to the respective plugin. + +The central functions of the block APIs (plugin and main library) are to +allow the mapping of blocks to their respective key (if possible) and +the ability to check that a block is well-formed and matches a given +request (again, if possible). This way, GNUnet can avoid storing invalid +blocks, storing blocks under the wrong key and forwarding blocks in +response to a query that they do not answer. + +One key function of block plugins is that it allows GNUnet to detect +duplicate replies (via the Bloom filter). All plugins MUST support +detecting duplicate replies (by adding the current response to the Bloom +filter and rejecting it if it is encountered again). If a plugin fails +to do this, responses may loop in the network. + +.. _Queries: + +Queries +^^^^^^^ + +The query format for any block in GNUnet consists of four main +components. First, the type of the desired block must be specified. +Second, the query must contain a hash code. The hash code is used for +lookups in hash tables and databases and must not be unique for the +block (however, if possible a unique hash should be used as this would +be best for performance). Third, an optional Bloom filter can be +specified to exclude known results; replies that hash to the bits set in +the Bloom filter are considered invalid. False-positives can be +eliminated by sending the same query again with a different Bloom filter +mutator value, which parametrizes the hash function that is used. +Finally, an optional application-specific \"eXtended query\" (xquery) +can be specified to further constrain the results. It is entirely up to +the type-specific plugin to determine whether or not a given block +matches a query (type, hash, Bloom filter, and xquery). Naturally, not +all xquery's are valid and some types of blocks may not support Bloom +filters either, so the plugin also needs to check if the query is valid +in the first place. + +Depending on the results from the plugin, the DHT will then discard the +(invalid) query, forward the query, discard the (invalid) reply, cache +the (valid) reply, and/or forward the (valid and non-duplicate) reply. + +.. _Sample-Code: + +Sample Code +^^^^^^^^^^^ + +The source code in **plugin_block_test.c** is a good starting point for +new block plugins --- it does the minimal work by implementing a plugin +that performs no validation at all. The respective **Makefile.am** shows +how to build and install a block plugin. + +.. _Conclusion2: + +Conclusion2 +^^^^^^^^^^^ + +In conclusion, GNUnet subsystems that want to use the DHT need to define +a block format and write a plugin to match queries and replies. For +testing, the ``GNUNET_BLOCK_TYPE_TEST`` block type can be used; it +accepts any query as valid and any reply as matching any query. This +type is also used for the DHT command line tools. However, it should NOT +be used for normal applications due to the lack of error checking that +results from this primitive implementation. + +libgnunetdht +:index:`libgnunetdht <single: libgnunet; dht>` +---------------------------------------------- + +The DHT API itself is pretty simple and offers the usual GET and PUT +functions that work as expected. The specified block type refers to the +block library which allows the DHT to run application-specific logic for +data stored in the network. + +.. _GET: + +GET +^^^ + +When using GET, the main consideration for developers (other than the +block library) should be that after issuing a GET, the DHT will +continuously cause (small amounts of) network traffic until the +operation is explicitly canceled. So GET does not simply send out a +single network request once; instead, the DHT will continue to search +for data. This is needed to achieve good success rates and also handles +the case where the respective PUT operation happens after the GET +operation was started. Developers should not cancel an existing GET +operation and then explicitly re-start it to trigger a new round of +network requests; this is simply inefficient, especially as the internal +automated version can be more efficient, for example by filtering +results in the network that have already been returned. + +If an application that performs a GET request has a set of replies that +it already knows and would like to filter, it can +call ``GNUNET_DHT_get_filter_known_results`` with an array of hashes +over the respective blocks to tell the DHT that these results are not +desired (any more). This way, the DHT will filter the respective blocks +using the block library in the network, which may result in a +significant reduction in bandwidth consumption. + +.. _PUT: + +PUT +^^^ + +.. todo:: inconsistent use of "must" above it's written "MUST" + +In contrast to GET operations, developers **must** manually re-run PUT +operations periodically (if they intend the content to continue to be +available). Content stored in the DHT expires or might be lost due to +churn. Furthermore, GNUnet's DHT typically requires multiple rounds of +PUT operations before a key-value pair is consistently available to all +peers (the DHT randomizes paths and thus storage locations, and only +after multiple rounds of PUTs there will be a sufficient number of +replicas in large DHTs). An explicit PUT operation using the DHT API +will only cause network traffic once, so in order to ensure basic +availability and resistance to churn (and adversaries), PUTs must be +repeated. While the exact frequency depends on the application, a rule +of thumb is that there should be at least a dozen PUT operations within +the content lifetime. Content in the DHT typically expires after one +day, so DHT PUT operations should be repeated at least every 1-2 hours. + +.. _MONITOR: + +MONITOR +^^^^^^^ + +The DHT API also allows applications to monitor messages crossing the +local DHT service. The types of messages used by the DHT are GET, PUT +and RESULT messages. Using the monitoring API, applications can choose +to monitor these requests, possibly limiting themselves to requests for +a particular block type. + +The monitoring API is not only useful for diagnostics, it can also be +used to trigger application operations based on PUT operations. For +example, an application may use PUTs to distribute work requests to +other peers. The workers would then monitor for PUTs that give them +work, instead of looking for work using GET operations. This can be +beneficial, especially if the workers have no good way to guess the keys +under which work would be stored. Naturally, additional protocols might +be needed to ensure that the desired number of workers will process the +distributed workload. + +.. _DHT-Routing-Options: + +DHT Routing Options +^^^^^^^^^^^^^^^^^^^ + +There are two important options for GET and PUT requests: + +GNUNET_DHT_RO_DEMULITPLEX_EVERYWHERE This option means that all + peers should process the request, even if their peer ID is not + closest to the key. For a PUT request, this means that all peers that + a request traverses may make a copy of the data. Similarly for a GET + request, all peers will check their local database for a result. + Setting this option can thus significantly improve caching and reduce + bandwidth consumption --- at the expense of a larger DHT database. If + in doubt, we recommend that this option should be used. + +GNUNET_DHT_RO_RECORD_ROUTE This option instructs the DHT to record + the path that a GET or a PUT request is taking through the overlay + network. The resulting paths are then returned to the application + with the respective result. This allows the receiver of a result to + construct a path to the originator of the data, which might then be + used for routing. Naturally, setting this option requires additional + bandwidth and disk space, so applications should only set this if the + paths are needed by the application logic. + +GNUNET_DHT_RO_FIND_PEER This option is an internal option used by + the DHT's peer discovery mechanism and should not be used by + applications. + +GNUNET_DHT_RO_BART This option is currently not implemented. It may + in the future offer performance improvements for clique topologies. + +.. _The-DHT-Client_002dService-Protocol: + +The DHT Client-Service Protocol +------------------------------- + +.. _PUTting-data-into-the-DHT: + +PUTting data into the DHT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +To store (PUT) data into the DHT, the client sends a +``struct GNUNET_DHT_ClientPutMessage`` to the service. This message +specifies the block type, routing options, the desired replication +level, the expiration time, key, value and a 64-bit unique ID for the +operation. The service responds with a +``struct GNUNET_DHT_ClientPutConfirmationMessage`` with the same 64-bit +unique ID. Note that the service sends the confirmation as soon as it +has locally processed the PUT request. The PUT may still be propagating +through the network at this time. + +In the future, we may want to change this to provide (limited) feedback +to the client, for example if we detect that the PUT operation had no +effect because the same key-value pair was already stored in the DHT. +However, changing this would also require additional state and messages +in the P2P interaction. + +.. _GETting-data-from-the-DHT: + +GETting data from the DHT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +To retrieve (GET) data from the DHT, the client sends a +``struct GNUNET_DHT_ClientGetMessage`` to the service. The message +specifies routing options, a replication level (for replicating the GET, +not the content), the desired block type, the key, the (optional) +extended query and unique 64-bit request ID. + +Additionally, the client may send any number of +``struct GNUNET_DHT_ClientGetResultSeenMessage``\ s to notify the +service about results that the client is already aware of. These +messages consist of the key, the unique 64-bit ID of the request, and an +arbitrary number of hash codes over the blocks that the client is +already aware of. As messages are restricted to 64k, a client that +already knows more than about a thousand blocks may need to send several +of these messages. Naturally, the client should transmit these messages +as quickly as possible after the original GET request such that the DHT +can filter those results in the network early on. Naturally, as these +messages are sent after the original request, it is conceivable that the +DHT service may return blocks that match those already known to the +client anyway. + +In response to a GET request, the service will send ``struct +GNUNET_DHT_ClientResultMessage``\ s to the client. These messages +contain the block type, expiration, key, unique ID of the request and of +course the value (a block). Depending on the options set for the +respective operations, the replies may also contain the path the GET +and/or the PUT took through the network. + +A client can stop receiving replies either by disconnecting or by +sending a ``struct GNUNET_DHT_ClientGetStopMessage`` which must contain +the key and the 64-bit unique ID of the original request. Using an +explicit \"stop\" message is more common as this allows a client to run +many concurrent GET operations over the same connection with the DHT +service --- and to stop them individually. + +.. _Monitoring-the-DHT: + +Monitoring the DHT +^^^^^^^^^^^^^^^^^^ + +To begin monitoring, the client sends a +``struct GNUNET_DHT_MonitorStartStop`` message to the DHT service. In +this message, flags can be set to enable (or disable) monitoring of GET, +PUT and RESULT messages that pass through a peer. The message can also +restrict monitoring to a particular block type or a particular key. Once +monitoring is enabled, the DHT service will notify the client about any +matching event using ``struct GNUNET_DHT_MonitorGetMessage``\ s for GET +events, ``struct GNUNET_DHT_MonitorPutMessage`` for PUT events and +``struct GNUNET_DHT_MonitorGetRespMessage`` for RESULTs. Each of these +messages contains all of the information about the event. + +.. _The-DHT-Peer_002dto_002dPeer-Protocol: + +The DHT Peer-to-Peer Protocol +----------------------------- + +.. _Routing-GETs-or-PUTs: + +Routing GETs or PUTs +^^^^^^^^^^^^^^^^^^^^ + +When routing GETs or PUTs, the DHT service selects a suitable subset of +neighbours for forwarding. The exact number of neighbours can be zero or +more and depends on the hop counter of the query (initially zero) in +relation to the (log of) the network size estimate, the desired +replication level and the peer's connectivity. Depending on the hop +counter and our network size estimate, the selection of the peers maybe +randomized or by proximity to the key. Furthermore, requests include a +set of peers that a request has already traversed; those peers are also +excluded from the selection. + +.. _PUTting-data-into-the-DHT2: + +PUTting data into the DHT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +To PUT data into the DHT, the service sends a ``struct PeerPutMessage`` +of type ``GNUNET_MESSAGE_TYPE_DHT_P2P_PUT`` to the respective neighbour. +In addition to the usual information about the content (type, routing +options, desired replication level for the content, expiration time, key +and value), the message contains a fixed-size Bloom filter with +information about which peers (may) have already seen this request. This +Bloom filter is used to ensure that DHT messages never loop back to a +peer that has already processed the request. Additionally, the message +includes the current hop counter and, depending on the routing options, +the message may include the full path that the message has taken so far. +The Bloom filter should already contain the identity of the previous +hop; however, the path should not include the identity of the previous +hop and the receiver should append the identity of the sender to the +path, not its own identity (this is done to reduce bandwidth). + +.. _GETting-data-from-the-DHT2: + +GETting data from the DHT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +A peer can search the DHT by sending ``struct PeerGetMessage``\ s of +type ``GNUNET_MESSAGE_TYPE_DHT_P2P_GET`` to other peers. In addition to +the usual information about the request (type, routing options, desired +replication level for the request, the key and the extended query), a +GET request also contains a hop counter, a Bloom filter over the peers +that have processed the request already and depending on the routing +options the full path traversed by the GET. Finally, a GET request +includes a variable-size second Bloom filter and a so-called Bloom +filter mutator value which together indicate which replies the sender +has already seen. During the lookup, each block that matches they block +type, key and extended query is additionally subjected to a test against +this Bloom filter. The block plugin is expected to take the hash of the +block and combine it with the mutator value and check if the result is +not yet in the Bloom filter. The originator of the query will from time +to time modify the mutator to (eventually) allow false-positives +filtered by the Bloom filter to be returned. + +Peers that receive a GET request perform a local lookup (depending on +their proximity to the key and the query options) and forward the +request to other peers. They then remember the request (including the +Bloom filter for blocking duplicate results) and when they obtain a +matching, non-filtered response a ``struct PeerResultMessage`` of type +``GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT`` is forwarded to the previous hop. +Whenever a result is forwarded, the block plugin is used to update the +Bloom filter accordingly, to ensure that the same result is never +forwarded more than once. The DHT service may also cache forwarded +results locally if the \"CACHE_RESULTS\" option is set to \"YES\" in the +configuration. + +.. [R5N2011] https://bib.gnunet.org/date.html#R5N diff --git a/man_developers/subsystems/fs/fs.rst b/man_developers/subsystems/fs/fs.rst @@ -0,0 +1,174 @@ +.. index:: + double: File sharing; subsystem + see: FS; File sharing + +.. _File_002dsharing-_0028FS_0029-Subsystem: + +FS — File sharing over GNUnet +============================= + +This chapter describes the details of how the file-sharing service +works. As with all services, it is split into an API (libgnunetfs), the +service process (gnunet-service-fs) and user interface(s). The +file-sharing service uses the datastore service to store blocks and the +DHT (and indirectly datacache) for lookups for non-anonymous +file-sharing. Furthermore, the file-sharing service uses the block +library (and the block fs plugin) for validation of DHT operations. + +In contrast to many other services, libgnunetfs is rather complex since +the client library includes a large number of high-level abstractions; +this is necessary since the FS service itself largely only operates on +the block level. The FS library is responsible for providing a +file-based abstraction to applications, including directories, meta +data, keyword search, verification, and so on. + +The method used by GNUnet to break large files into blocks and to use +keyword search is called the \"Encoding for Censorship Resistant +Sharing\" (ECRS). ECRS is largely implemented in the fs library; block +validation is also reflected in the block FS plugin and the FS service. +ECRS on-demand encoding is implemented in the FS service. + +.. note:: The documentation in this chapter is quite incomplete. + +.. _Encoding-for-Censorship_002dResistant-Sharing-_0028ECRS_0029: + +.. index:: + see: Encoding for Censorship-Resistant Sharing; ECRS + +:index:`ECRS — Encoding for Censorship-Resistant Sharing <single: ECRS>` +------------------------------------------------------------------------ + +When GNUnet shares files, it uses a content encoding that is called +ECRS, the Encoding for Censorship-Resistant Sharing. Most of ECRS is +described in the (so far unpublished) research paper attached to this +page. ECRS obsoletes the previous ESED and ESED II encodings which were +used in GNUnet before version 0.7.0. The rest of this page assumes that +the reader is familiar with the attached paper. What follows is a +description of some minor extensions that GNUnet makes over what is +described in the paper. The reason why these extensions are not in the +paper is that we felt that they were obvious or trivial extensions to +the original scheme and thus did not warrant space in the research +report. + +.. todo:: Find missing link to file system paper. + +.. _Namespace-Advertisements: + +Namespace Advertisements +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. todo:: FIXME: all zeroses -> ? + +An ``SBlock`` with identifier all zeros is a signed advertisement for a +namespace. This special ``SBlock`` contains metadata describing the +content of the namespace. Instead of the name of the identifier for a +potential update, it contains the identifier for the root of the +namespace. The URI should always be empty. The ``SBlock`` is signed with +the content provider's RSA private key (just like any other SBlock). +Peers can search for ``SBlock``\ s in order to find out more about a +namespace. + +.. _KSBlocks: + +KSBlocks +^^^^^^^^ + +GNUnet implements ``KSBlocks`` which are ``KBlocks`` that, instead of +encrypting a CHK and metadata, encrypt an ``SBlock`` instead. In other +words, ``KSBlocks`` enable GNUnet to find ``SBlocks`` using the global +keyword search. Usually the encrypted ``SBlock`` is a namespace +advertisement. The rationale behind ``KSBlock``\ s and ``SBlock``\ s is +to enable peers to discover namespaces via keyword searches, and, to +associate useful information with namespaces. When GNUnet finds +``KSBlocks`` during a normal keyword search, it adds the information to +an internal list of discovered namespaces. Users looking for interesting +namespaces can then inspect this list, reducing the need for out-of-band +discovery of namespaces. Naturally, namespaces (or more specifically, +namespace advertisements) can also be referenced from directories, but +``KSBlock``\ s should make it easier to advertise namespaces for the +owner of the pseudonym since they eliminate the need to first create a +directory. + +Collections are also advertised using ``KSBlock``\ s. + +.. https://old.gnunet.org/sites/default/files/ecrs.pdf +.. What is this? - WGL + +.. _File_002dsharing-persistence-directory-structure: + +File-sharing persistence directory structure +-------------------------------------------- + +This section documents how the file-sharing library implements +persistence of file-sharing operations and specifically the resulting +directory structure. This code is only active if the +``GNUNET_FS_FLAGS_PERSISTENCE`` flag was set when calling +``GNUNET_FS_start``. In this case, the file-sharing library will try +hard to ensure that all major operations (searching, downloading, +publishing, unindexing) are persistent, that is, can live longer than +the process itself. More specifically, an operation is supposed to live +until it is explicitly stopped. + +If ``GNUNET_FS_stop`` is called before an operation has been stopped, a +``SUSPEND`` event is generated and then when the process calls +``GNUNET_FS_start`` next time, a ``RESUME`` event is generated. +Additionally, even if an application crashes (segfault, SIGKILL, system +crash) and hence ``GNUNET_FS_stop`` is never called and no ``SUSPEND`` +events are generated, operations are still resumed (with ``RESUME`` +events). This is implemented by constantly writing the current state of +the file-sharing operations to disk. Specifically, the current state is +always written to disk whenever anything significant changes (the +exception are block-wise progress in publishing and unindexing, since +those operations would be slowed down significantly and can be resumed +cheaply even without detailed accounting). Note that if the process +crashes (or is killed) during a serialization operation, FS does not +guarantee that this specific operation is recoverable (no strict +transactional semantics, again for performance reasons). However, all +other unrelated operations should resume nicely. + +Since we need to serialize the state continuously and want to recover as +much as possible even after crashing during a serialization operation, +we do not use one large file for serialization. Instead, several +directories are used for the various operations. When +``GNUNET_FS_start`` executes, the master directories are scanned for +files describing operations to resume. Sometimes, these operations can +refer to related operations in child directories which may also be +resumed at this point. Note that corrupted files are cleaned up +automatically. However, dangling files in child directories (those that +are not referenced by files from the master directories) are not +automatically removed. + +Persistence data is kept in a directory that begins with the +\"STATE_DIR\" prefix from the configuration file (by default, +\"$SERVICEHOME/persistence/\") followed by the name of the client as +given to ``GNUNET_FS_start`` (for example, \"gnunet-gtk\") followed by +the actual name of the master or child directory. + +The names for the master directories follow the names of the operations: + +- \"search\" + +- \"download\" + +- \"publish\" + +- \"unindex\" + +Each of the master directories contains names (chosen at random) for +each active top-level (master) operation. Note that a download that is +associated with a search result is not a top-level operation. + +In contrast to the master directories, the child directories are only +consulted when another operation refers to them. For each search, a +subdirectory (named after the master search synchronization file) +contains the search results. Search results can have an associated +download, which is then stored in the general \"download-child\" +directory. Downloads can be recursive, in which case children are stored +in subdirectories mirroring the structure of the recursive download +(either starting in the master \"download\" directory or in the +\"download-child\" directory depending on how the download was +initiated). For publishing operations, the \"publish-file\" directory +contains information about the individual files and directories that are +part of the publication. However, this directory structure is flat and +does not mirror the structure of the publishing operation. Note that +unindex operations cannot have associated child operations. diff --git a/man_developers/subsystems/gns/gns.rst b/man_developers/subsystems/gns/gns.rst @@ -0,0 +1,616 @@ +.. index:: + double: GNU Name System; subsystem + see: GNS; GNU Name System + +.. _GNU-Name-System-_0028GNS_0029: + +GNS — the GNU Name System +========================= + +The GNU Name System (GNS) is a decentralized database that enables users +to securely resolve names to values. Names can be used to identify other +users (for example, in social networking), or network services (for +example, VPN services running at a peer in GNUnet, or purely IP-based +services on the Internet). Users interact with GNS by typing in a +hostname that ends in a top-level domain that is configured in the "GNS" +section, matches an identity of the user or ends in a Base32-encoded +public key. + +Videos giving an overview of most of the GNS and the motivations behind +it is available here and here. The remainder of this chapter targets +developers that are familiar with high level concepts of GNS as +presented in these talks. + +.. todo:: Link to videos and GNS talks? + +GNS-aware applications should use the GNS resolver to obtain the +respective records that are stored under that name in GNS. Each record +consists of a type, value, expiration time and flags. + +The type specifies the format of the value. Types below 65536 correspond +to DNS record types, larger values are used for GNS-specific records. +Applications can define new GNS record types by reserving a number and +implementing a plugin (which mostly needs to convert the binary value +representation to a human-readable text format and vice-versa). The +expiration time specifies how long the record is to be valid. The GNS +API ensures that applications are only given non-expired values. The +flags are typically irrelevant for applications, as GNS uses them +internally to control visibility and validity of records. + +Records are stored along with a signature. The signature is generated +using the private key of the authoritative zone. This allows any GNS +resolver to verify the correctness of a name-value mapping. + +Internally, GNS uses the NAMECACHE to cache information obtained from +other users, the NAMESTORE to store information specific to the local +users, and the DHT to exchange data between users. A plugin API is used +to enable applications to define new GNS record types. + + +:index:`libgnunetgns <single: libgnunet; gns>` +---------------------------------------------- + +The GNS API itself is extremely simple. Clients first connect to the GNS +service using ``GNUNET_GNS_connect``. They can then perform lookups +using ``GNUNET_GNS_lookup`` or cancel pending lookups using +``GNUNET_GNS_lookup_cancel``. Once finished, clients disconnect using +``GNUNET_GNS_disconnect``. + +.. _Looking-up-records: + +Looking up records +^^^^^^^^^^^^^^^^^^ + +``GNUNET_GNS_lookup`` takes a number of arguments: + +handle This is simply the GNS connection handle from + ``GNUNET_GNS_connect``. + +name The client needs to specify the name to + be resolved. This can be any valid DNS or GNS hostname. + +zone The client + needs to specify the public key of the GNS zone against which the + resolution should be done. Note that a key must be provided, the + client should look up plausible values using its configuration, the + identity service and by attempting to interpret the TLD as a + base32-encoded public key. + +type This is the desired GNS or DNS record type + to look for. While all records for the given name will be returned, + this can be important if the client wants to resolve record types + that themselves delegate resolution, such as CNAME, PKEY or GNS2DNS. + Resolving a record of any of these types will only work if the + respective record type is specified in the request, as the GNS + resolver will otherwise follow the delegation and return the records + from the respective destination, instead of the delegating record. + +only_cached This argument should typically be set to + ``GNUNET_NO``. Setting it to ``GNUNET_YES`` disables resolution via + the overlay network. + +shorten_zone_key If GNS encounters new names during resolution, + their respective zones can automatically be learned and added to the + \"shorten zone\". If this is desired, clients must pass the private + key of the shorten zone. If NULL is passed, shortening is disabled. + +proc This argument identifies + the function to call with the result. It is given proc_cls, the + number of records found (possibly zero) and the array of the records + as arguments. proc will only be called once. After proc,> has been + called, the lookup must no longer be canceled. + +proc_cls The closure for proc. + +.. _Accessing-the-records: + +Accessing the records +^^^^^^^^^^^^^^^^^^^^^ + +The ``libgnunetgnsrecord`` library provides an API to manipulate the GNS +record array that is given to proc. In particular, it offers functions +such as converting record values to human-readable strings (and back). +However, most ``libgnunetgnsrecord`` functions are not interesting to +GNS client applications. + +For DNS records, the ``libgnunetdnsparser`` library provides functions +for parsing (and serializing) common types of DNS records. + +.. _Creating-records: + +Creating records +^^^^^^^^^^^^^^^^ + +Creating GNS records is typically done by building the respective record +information (possibly with the help of ``libgnunetgnsrecord`` and +``libgnunetdnsparser``) and then using the ``libgnunetnamestore`` to +publish the information. The GNS API is not involved in this operation. + +.. _Future-work: + +Future work +^^^^^^^^^^^ + +In the future, we want to expand ``libgnunetgns`` to allow applications +to observe shortening operations performed during GNS resolution, for +example so that users can receive visual feedback when this happens. + +libgnunetgnsrecord +~~~~~~~~~~~~~~~~~~ + +The ``libgnunetgnsrecord`` library is used to manipulate GNS records (in +plaintext or in their encrypted format). Applications mostly interact +with ``libgnunetgnsrecord`` by using the functions to convert GNS record +values to strings or vice-versa, or to lookup a GNS record type number +by name (or vice-versa). The library also provides various other +functions that are mostly used internally within GNS, such as converting +keys to names, checking for expiration, encrypting GNS records to GNS +blocks, verifying GNS block signatures and decrypting GNS records from +GNS blocks. + +We will now discuss the four commonly used functions of the +API. ``libgnunetgnsrecord`` does not perform these operations itself, +but instead uses plugins to perform the operation. GNUnet includes +plugins to support common DNS record types as well as standard GNS +record types. + +.. _Value-handling: + +Value handling +^^^^^^^^^^^^^^ + +``GNUNET_GNSRECORD_value_to_string`` can be used to convert the (binary) +representation of a GNS record value to a human readable, 0-terminated +UTF-8 string. NULL is returned if the specified record type is not +supported by any available plugin. + +``GNUNET_GNSRECORD_string_to_value`` can be used to try to convert a +human readable string to the respective (binary) representation of a GNS +record value. + +.. _Type-handling: + +Type handling +^^^^^^^^^^^^^ + +``GNUNET_GNSRECORD_typename_to_number`` can be used to obtain the +numeric value associated with a given typename. For example, given the +typename \"A\" (for DNS A reocrds), the function will return the number +1. A list of common DNS record types is +`here <http://en.wikipedia.org/wiki/List_of_DNS_record_types>`__. Note +that not all DNS record types are supported by GNUnet GNSRECORD plugins +at this time. + +``GNUNET_GNSRECORD_number_to_typename`` can be used to obtain the +typename associated with a given numeric value. For example, given the +type number 1, the function will return the typename \"A\". + +.. _GNS-plugins: + +GNS plugins +~~~~~~~~~~~ + +Adding a new GNS record type typically involves writing (or extending) a +GNSRECORD plugin. The plugin needs to implement the +``gnunet_gnsrecord_plugin.h`` API which provides basic functions that +are needed by GNSRECORD to convert typenames and values of the +respective record type to strings (and back). These gnsrecord plugins +are typically implemented within their respective subsystems. Examples +for such plugins can be found in the GNSRECORD, GNS and CONVERSATION +subsystems. + +The ``libgnunetgnsrecord`` library is then used to locate, load and +query the appropriate gnsrecord plugin. Which plugin is appropriate is +determined by the record type (which is just a 32-bit integer). The +``libgnunetgnsrecord`` library loads all block plugins that are +installed at the local peer and forwards the application request to the +plugins. If the record type is not supported by the plugin, it should +simply return an error code. + +The central functions of the block APIs (plugin and main library) are +the same four functions for converting between values and strings, and +typenames and numbers documented in the previous subsection. + +.. _The-GNS-Client_002dService-Protocol: + +The GNS Client-Service Protocol +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The GNS client-service protocol consists of two simple messages, the +``LOOKUP`` message and the ``LOOKUP_RESULT``. Each ``LOOKUP`` message +contains a unique 32-bit identifier, which will be included in the +corresponding response. Thus, clients can send many lookup requests in +parallel and receive responses out-of-order. A ``LOOKUP`` request also +includes the public key of the GNS zone, the desired record type and +fields specifying whether shortening is enabled or networking is +disabled. Finally, the ``LOOKUP`` message includes the name to be +resolved. + +The response includes the number of records and the records themselves +in the format created by ``GNUNET_GNSRECORD_records_serialize``. They +can thus be deserialized using ``GNUNET_GNSRECORD_records_deserialize``. + +.. _Hijacking-the-DNS_002dTraffic-using-gnunet_002dservice_002ddns: + +Hijacking the DNS-Traffic using gnunet-service-dns +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section documents how the gnunet-service-dns (and the +gnunet-helper-dns) intercepts DNS queries from the local system. This is +merely one method for how we can obtain GNS queries. It is also possible +to change ``resolv.conf`` to point to a machine running +``gnunet-dns2gns`` or to modify libc's name system switch (NSS) +configuration to include a GNS resolution plugin. The method described +in this chapter is more of a last-ditch catch-all approach. + +``gnunet-service-dns`` enables intercepting DNS traffic using policy +based routing. We MARK every outgoing DNS-packet if it was not sent by +our application. Using a second routing table in the Linux kernel these +marked packets are then routed through our virtual network interface and +can thus be captured unchanged. + +Our application then reads the query and decides how to handle it. If +the query can be addressed via GNS, it is passed to +``gnunet-service-gns`` and resolved internally using GNS. In the future, +a reverse query for an address of the configured virtual network could +be answered with records kept about previous forward queries. Queries +that are not hijacked by some application using the DNS service will be +sent to the original recipient. The answer to the query will always be +sent back through the virtual interface with the original nameserver as +source address. + +.. _Network-Setup-Details: + +Network Setup Details +^^^^^^^^^^^^^^^^^^^^^ + +The DNS interceptor adds the following rules to the Linux kernel: + +:: + + iptables -t mangle -I OUTPUT 1 -p udp --sport $LOCALPORT --dport 53 \ + -j ACCEPT iptables -t mangle -I OUTPUT 2 -p udp --dport 53 -j MARK \ + --set-mark 3 ip rule add fwmark 3 table2 ip route add default via \ + $VIRTUALDNS table2 + +.. todo:: + FIXME: Rewrite to reflect display which is no longer content + by line due to the < 74 characters limit. + +Line 1 makes sure that all packets coming from a port our application +opened beforehand (``$LOCALPORT``) will be routed normally. Line 2 marks +every other packet to a DNS-Server with mark 3 (chosen arbitrarily). The +third line adds a routing policy based on this mark 3 via the routing +table. + +.. _Importing-DNS-Zones-into-GNS: + +Importing DNS Zones into GNS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section discusses the challenges and problems faced when writing +the Ascension tool. It also takes a look at possible improvements in the +future. + +Consider the following diagram that shows the workflow of Ascension: + +|ascension| + +Further the interaction between components of GNUnet are shown in the +diagram below: + +DNS Conversion +.. _Conversions-between-DNS-and-GNS: + +Conversions between DNS and GNS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The differences between the two name systems lies in the details and is +not always transparent. For instance an SRV record is converted to a BOX +record which is unique to GNS. + +This is done by converting to a BOX record from an existing SRV record: + +:: + + # SRV + # _service._proto.name. TTL class SRV priority weight port target + _sip._tcp.example.com. 14000 IN SRV 0 0 5060 www.example.com. + # BOX + # TTL BOX flags port protocol recordtype priority weight port target + 14000 BOX n 5060 6 33 0 0 5060 www.example.com + +Other records that need to undergo such transformation is the MX record +type, as well as the SOA record type. + +Transformation of a SOA record into GNS works as described in the +following example. Very important to note are the rname and mname keys. + +:: + + # BIND syntax for a clean SOA record + IN SOA master.example.com. hostmaster.example.com. ( + 2017030300 ; serial + 3600 ; refresh + 1800 ; retry + 604800 ; expire + 600 ) ; ttl + # Recordline for adding the record + $ gnunet-namestore -z example.com -a -n -t SOA -V \ + rname=master.example.com mname=hostmaster.example.com \ + 2017030300,3600,1800,604800,600 -e 7200s + +The transformation of MX records is done in a simple way. + +:: + + # mail.example.com. 3600 IN MX 10 mail.example.com. + $ gnunet-namestore -z example.com -n mail -R 3600 MX n 10,mail + +Finally, one of the biggest struggling points were the NS records that +are found in top level domain zones. The intended behaviour for those is +to add GNS2DNS records for those so that gnunet-gns can resolve records +for those domains on its own. Those require the values from DNS GLUE +records, provided they are within the same zone. + +The following two examples show one record with a GLUE record and the +other one does not have a GLUE record. This takes place in the 'com' +TLD. + +.. code-block:: shell + + # ns1.example.com 86400 IN A 127.0.0.1 + # example.com 86400 IN NS ns1.example.com. + $ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \ + example.com@127.0.0.1 + + # example.com 86400 IN NS ns1.example.org. + $ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \ + example.com@ns1.example.org + +As you can see, one of the GNS2DNS records has an IP address listed and +the other one a DNS name. For the first one there is a GLUE record to do +the translation directly and the second one will issue another DNS query +to figure out the IP of ns1.example.org. + +A solution was found by creating a hierarchical zone structure in GNS +and linking the zones using PKEY records to one another. This allows the +resolution of the name servers to work within GNS while not taking +control over unwanted zones. + +Currently the following record types are supported: + +- A + +- AAAA + +- CNAME + +- MX + +- NS + +- SRV + +- TXT + +This is not due to technical limitations but rather a practical ones. +The problem occurs with DNSSEC enabled DNS zones. As records within +those zones are signed periodically, and every new signature is an +update to the zone, there are many revisions of zones. This results in a +problem with bigger zones as there are lots of records that have been +signed again but no major changes. Also trying to add records that are +unknown that require a different format take time as they cause a CLI +call of the namestore. Furthermore certain record types need +transformation into a GNS compatible format which, depending on the +record type, takes more time. + +Further a blacklist was added to drop for instance DNSSEC related +records. Also if a record type is neither in the white list nor the +blacklist it is considered as a loss of data and a message is shown to +the user. This helps with transparency and also with contributing, as +the not supported record types can then be added accordingly. + +.. _DNS-Zone-Size: + +DNS Zone Size +^^^^^^^^^^^^^ + +Another very big problem exists with very large zones. When migrating a +small zone the delay between adding of records and their expiry is +negligible. However when working with big zones that easily have more +than a few million records this delay becomes a problem. + +Records will start to expire well before the zone has finished +migrating. This is usually not a problem but can cause a high CPU load +when a peer is restarted and the records have expired. + +A good solution has not been found yet. One of the idea that floated +around was that the records should be added with the s (shadow) flag to +keep the records resolvable even if they expired. However this would +introduce the problem of how to detect if a record has been removed from +the zone and would require deletion of said record(s). + +Another problem that still persists is how to refresh records. Expired +records are still displayed when calling gnunet-namestore but do not +resolve with gnunet-gns. Zonemaster will sign the expired records again +and make sure that the records are still valid. With a recent change +this was fixed as gnunet-gns to improve the suffix lookup which allows +for a fast lookup even with thousands of local egos. + +Currently the pace of adding records in general is around 10 records per +second. Crypto is the upper limit for adding of records. The performance +of your machine can be tested with the perf_crypto\_\* tools. There is +still a big discrepancy between the pace of Ascension and the +theoretical limit. + +A performance metric for measuring improvements has not yet been +implemented in Ascension. + +.. _Performance: + +Performance +^^^^^^^^^^^ + +The performance when migrating a zone using the Ascension tool is +limited by a handful of factors. First of all ascension is written in +Python3 and calls the CLI tools of GNUnet. This is comparable to a fork +and exec call which costs a few CPU cycles. Furthermore all the records +that are added to the same label are signed using the zones private key. +This signing operation is very resource heavy and was optimized during +development by adding the '-R' (Recordline) option to gnunet-namestore +which allows to specify multiple records using the CLI tool. Assuming +that in a TLD zone every domain has at least two name servers this +halves the amount of signatures needed. + +Another improvement that could be made is with the addition of multiple +threads or using asynchronous subprocesses when opening the GNUnet CLI +tools. This could be implemented by simply creating more workers in the +program but performance improvements were not tested. + +Ascension was tested using different hardware and database backends. +Performance differences between SQLite and postgresql are marginal and +almost non existent. What did make a huge impact on record adding +performance was the storage medium. On a traditional mechanical hard +drive adding of records were slow compared to a solid state disk. + +In conclusion there are many bottlenecks still around in the program, +namely the single threaded implementation and inefficient, sequential +calls of gnunet-namestore. In the future a solution that uses the C API +would be cleaner and better. + +.. _Registering-names-using-the-FCFS-daemon: + +Registering names using the FCFS daemon +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section describes FCFSD, a daemon used to associate names with PKEY +records following a "First Come, First Served" policy. This policy means +that a certain name can not be registered again if someone registered it +already. + +The daemon can be started by using ``gnunet-namestore-fcfsd``, which +will start a simple HTTP server on localhost, using a port specified by +the ``HTTPORT`` value in its configuration. + +Communication is performed by sending GET or POST requests to specific +paths ("endpoints"), as described in the following sections. + +The daemon will always respond with data structured using the JSON +format. The fields to be expected will be listed for each endpoint. + +The only exceptions are for the "root" endpoint (i.e. ``/``) which will +return a HTML document, and two other HTML documents which will be +served when certain errors are encountered, like when requesting an +unknown endpoint. + +FCFSD GET requests +.. _Obtaining-information-from-the-daemon: + +Obtaining information from the daemon +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To query the daemon, a GET request must be sent to these endpoints, +placing parameters in the address as per the HTTP specification, like +so: + +:: + + GET /endpoint?param1=value¶m2=value + +Each endpoint will be described using its name (``/endpoint`` in the +example above), followed by the name of each parameter (like ``param1`` +and ``param2``.) + + +**Endpoint: /search** :bolditalic:`name` + This endpoint is used to query about the state of <name>, that is, + whether it is available for registration or not. + + The response JSON will contain two fields: + + - error + + - free + + ``error`` can be either the string ``"true"`` or the string + ``"false"``: when ``"true"``, it means there was an error within the + daemon and the name could not be searched at all. + + ``free`` can be either the string ``"true"`` or the string + ``"false"``: when ``"true"``, the requested name can be registered. + +FCFSD POST requests +.. _Submitting-data-to-the-daemon: + +Submitting data to the daemon +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To send data to the daemon, a POST request must be sent to these +endpoints, placing the data to submit in the body of the request, +structured using the JSON format, like so: + +:: + + POST /endpoint + Content-Type: application/json + ... + + {"param1": value1, "param2": value2, ...} + +Each endpoint will be described using its name (``/endpoint`` in the +example above), followed by the name of each JSON field (like ``param1`` +and ``param2``.) + +**Endpoint: /register** :bolditalic:`name key` + This endpoint is used to register a new association between <name> + and <key>. + + For this operation to succeed, both <NAME> and <KEY> **must not** be + registered already. + + The response JSON will contain two fields: + + - error + + - message + + ``error`` can be either the string ``"true"`` or the string + ``"false"``: when ``"true"``, it means the name could not be + registered. Clients can get the reason of the failure from the HTTP + response code or from the ``message`` field. + + ``message`` is a string which can be used by clients to let users + know the result of the operation. It might be localized to the daemon + operator's locale. + +.. _Customizing-the-HTML-output: + +Customizing the HTML output +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In some situations, the daemon will serve HTML documents instead of JSON +values. It is possible to configure the daemon to serve custom documents +instead of the ones provided with GNUnet, by setting the ``HTMLDIR`` +value in its configuration to a directory path. + +Within the provided path, the daemon will search for these three files: + +- fcfsd-index.html + +- fcfsd-notfound.html + +- fcfsd-forbidden.html + +The ``fcfsd-index.html`` file is the daemon's "homepage": operators +might want to provide information about the service here, or provide a +form with which it is possible to register a name. + +The ``fcfsd-notfound.html`` file is used primarily to let users know +they tried to access an unknown endpoint. + +The ``fcfsd-forbidden.html`` file is served to users when they try to +access an endpoint they should not access. For example, sending an +invalid request might result in this page being served. + +.. |ascension| image:: /_static/images/ascension_ssd.png diff --git a/man_developers/subsystems/gnsstack.rst b/man_developers/subsystems/gnsstack.rst @@ -0,0 +1,12 @@ + +GNS and GNS Support +=================== + +The GNU Name System is a secure and censorship-resistant +alternative to the Domain Name System (DNS) in common use for +resolving domain names. + +.. toctree:: + gns/gns.rst + namecache/namecache.rst + namestore/namestore.rst diff --git a/man_developers/subsystems/hostlist/hostlist.rst b/man_developers/subsystems/hostlist/hostlist.rst @@ -0,0 +1,290 @@ + +.. index:: + double: HOSTLIST; subsystem + +.. _HOSTLIST-Subsystem: + +HOSTLIST — HELLO bootstrapping and gossip +========================================= + +Peers in the GNUnet overlay network need address information so that +they can connect with other peers. GNUnet uses so called HELLO messages +to store and exchange peer addresses. GNUnet provides several methods +for peers to obtain this information: + +- out-of-band exchange of HELLO messages (manually, using for example + gnunet-peerinfo) + +- HELLO messages shipped with GNUnet (automatic with distribution) + +- UDP neighbor discovery in LAN (IPv4 broadcast, IPv6 multicast) + +- topology gossiping (learning from other peers we already connected + to), and + +- the HOSTLIST daemon covered in this section, which is particularly + relevant for bootstrapping new peers. + +New peers have no existing connections (and thus cannot learn from +gossip among peers), may not have other peers in their LAN and might be +started with an outdated set of HELLO messages from the distribution. In +this case, getting new peers to connect to the network requires either +manual effort or the use of a HOSTLIST to obtain HELLOs. + +.. _HELLOs: + +HELLOs +------ + +The basic information peers require to connect to other peers are +contained in so called HELLO messages you can think of as a business +card. Besides the identity of the peer (based on the cryptographic +public key) a HELLO message may contain address information that +specifies ways to contact a peer. By obtaining HELLO messages, a peer +can learn how to contact other peers. + +.. _Overview-for-the-HOSTLIST-subsystem: + +Overview for the HOSTLIST subsystem +----------------------------------- + +The HOSTLIST subsystem provides a way to distribute and obtain contact +information to connect to other peers using a simple HTTP GET request. +Its implementation is split in three parts, the main file for the +daemon itself (``gnunet-daemon-hostlist.c``), the HTTP client used to +download peer information (``hostlist-client.c``) and the server +component used to provide this information to other peers +(``hostlist-server.c``). The server is basically a small HTTP web server +(based on GNU libmicrohttpd) which provides a list of HELLOs known to +the local peer for download. The client component is basically a HTTP +client (based on libcurl) which can download hostlists from one or more +websites. The hostlist format is a binary blob containing a sequence of +HELLO messages. Note that any HTTP server can theoretically serve a +hostlist, the built-in hostlist server makes it simply convenient to +offer this service. + +.. _Features: + +Features +^^^^^^^^ + +The HOSTLIST daemon can: + +- provide HELLO messages with validated addresses obtained from + PEERINFO to download for other peers + +- download HELLO messages and forward these message to the TRANSPORT + subsystem for validation + +- advertises the URL of this peer's hostlist address to other peers via + gossip + +- automatically learn about hostlist servers from the gossip of other + peers + +.. _HOSTLIST-_002d-Limitations: + +HOSTLIST - Limitations +^^^^^^^^^^^^^^^^^^^^^^ + +The HOSTLIST daemon does not: + +- verify the cryptographic information in the HELLO messages + +- verify the address information in the HELLO messages + +.. _Interacting-with-the-HOSTLIST-daemon: + +Interacting with the HOSTLIST daemon +------------------------------------ + +The HOSTLIST subsystem is currently implemented as a daemon, so there is +no need for the user to interact with it and therefore there is no +command line tool and no API to communicate with the daemon. In the +future, we can envision changing this to allow users to manually trigger +the download of a hostlist. + +Since there is no command line interface to interact with HOSTLIST, the +only way to interact with the hostlist is to use STATISTICS to obtain or +modify information about the status of HOSTLIST: + +:: + + $ gnunet-statistics -s hostlist + +In particular, HOSTLIST includes a **persistent** value in statistics +that specifies when the hostlist server might be queried next. As this +value is exponentially increasing during runtime, developers may want to +reset or manually adjust it. Note that HOSTLIST (but not STATISTICS) +needs to be shutdown if changes to this value are to have any effect on +the daemon (as HOSTLIST does not monitor STATISTICS for changes to the +download frequency). + +.. _Hostlist-security-address-validation: + +Hostlist security address validation +------------------------------------ + +Since information obtained from other parties cannot be trusted without +validation, we have to distinguish between *validated* and *not +validated* addresses. Before using (and so trusting) information from +other parties, this information has to be double-checked (validated). +Address validation is not done by HOSTLIST but by the TRANSPORT service. + +The HOSTLIST component is functionally located between the PEERINFO and +the TRANSPORT subsystem. When acting as a server, the daemon obtains +valid (*validated*) peer information (HELLO messages) from the PEERINFO +service and provides it to other peers. When acting as a client, it +contacts the HOSTLIST servers specified in the configuration, downloads +the (unvalidated) list of HELLO messages and forwards these information +to the TRANSPORT server to validate the addresses. + +.. _The-HOSTLIST-daemon: + +:index:`The HOSTLIST daemon <double: daemon; HOSTLIST>` +------------------------------------------------------- + +The hostlist daemon is the main component of the HOSTLIST subsystem. It +is started by the ARM service and (if configured) starts the HOSTLIST +client and server components. + +GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT +If the daemon provides a hostlist itself it can advertise it's own +hostlist to other peers. To do so it sends a +``GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT`` message to other peers +when they connect to this peer on the CORE level. This hostlist +advertisement message contains the URL to access the HOSTLIST HTTP +server of the sender. The daemon may also subscribe to this type of +message from CORE service, and then forward these kind of message to the +HOSTLIST client. The client then uses all available URLs to download +peer information when necessary. + +When starting, the HOSTLIST daemon first connects to the CORE subsystem +and if hostlist learning is enabled, registers a CORE handler to receive +this kind of messages. Next it starts (if configured) the client and +server. It passes pointers to CORE connect and disconnect and receive +handlers where the client and server store their functions, so the +daemon can notify them about CORE events. + +To clean up on shutdown, the daemon has a cleaning task, shutting down +all subsystems and disconnecting from CORE. + +.. _The-HOSTLIST-server: + +:index:`The HOSTLIST server <single: HOSTLIST; server>` +------------------------------------------------------- + +The server provides a way for other peers to obtain HELLOs. Basically it +is a small web server other peers can connect to and download a list of +HELLOs using standard HTTP; it may also advertise the URL of the +hostlist to other peers connecting on CORE level. + +.. _The-HTTP-Server: + +The HTTP Server +^^^^^^^^^^^^^^^ + +During startup, the server starts a web server listening on the port +specified with the HTTPPORT value (default 8080). In addition it +connects to the PEERINFO service to obtain peer information. The +HOSTLIST server uses the GNUNET_PEERINFO_iterate function to request +HELLO information for all peers and adds their information to a new +hostlist if they are suitable (expired addresses and HELLOs without +addresses are both not suitable) and the maximum size for a hostlist is +not exceeded (MAX_BYTES_PER_HOSTLISTS = 500000). When PEERINFO finishes +(with a last NULL callback), the server destroys the previous hostlist +response available for download on the web server and replaces it with +the updated hostlist. The hostlist format is basically a sequence of +HELLO messages (as obtained from PEERINFO) without any special +tokenization. Since each HELLO message contains a size field, the +response can easily be split into separate HELLO messages by the client. + +A HOSTLIST client connecting to the HOSTLIST server will receive the +hostlist as an HTTP response and the server will terminate the +connection with the result code ``HTTP 200 OK``. The connection will be +closed immediately if no hostlist is available. + +.. _Advertising-the-URL: + +Advertising the URL +^^^^^^^^^^^^^^^^^^^ + +The server also advertises the URL to download the hostlist to other +peers if hostlist advertisement is enabled. When a new peer connects and +has hostlist learning enabled, the server sends a +``GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT`` message to this peer +using the CORE service. + +HOSTLIST client +.. _The-HOSTLIST-client: + +The HOSTLIST client +------------------- + +The client provides the functionality to download the list of HELLOs +from a set of URLs. It performs a standard HTTP request to the URLs +configured and learned from advertisement messages received from other +peers. When a HELLO is downloaded, the HOSTLIST client forwards the +HELLO to the TRANSPORT service for validation. + +The client supports two modes of operation: + +- download of HELLOs (bootstrapping) + +- learning of URLs + +.. _Bootstrapping: + +Bootstrapping +^^^^^^^^^^^^^ + +For bootstrapping, it schedules a task to download the hostlist from the +set of known URLs. The downloads are only performed if the number of +current connections is smaller than a minimum number of connections (at +the moment 4). The interval between downloads increases exponentially; +however, the exponential growth is limited if it becomes longer than an +hour. At that point, the frequency growth is capped at (#number of +connections \* 1h). + +Once the decision has been taken to download HELLOs, the daemon chooses +a random URL from the list of known URLs. URLs can be configured in the +configuration or be learned from advertisement messages. The client uses +a HTTP client library (libcurl) to initiate the download using the +libcurl multi interface. Libcurl passes the data to the +callback_download function which stores the data in a buffer if space is +available and the maximum size for a hostlist download is not exceeded +(MAX_BYTES_PER_HOSTLISTS = 500000). When a full HELLO was downloaded, +the HOSTLIST client offers this HELLO message to the TRANSPORT service +for validation. When the download is finished or failed, statistical +information about the quality of this URL is updated. + +.. _Learning: + +:index:`Learning <single: HOSTLIST; learning>` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The client also manages hostlist advertisements from other peers. The +HOSTLIST daemon forwards ``GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT`` +messages to the client subsystem, which extracts the URL from the +message. Next, a test of the newly obtained URL is performed by +triggering a download from the new URL. If the URL works correctly, it +is added to the list of working URLs. + +The size of the list of URLs is restricted, so if an additional server +is added and the list is full, the URL with the worst quality ranking +(determined through successful downloads and number of HELLOs e.g.) is +discarded. During shutdown the list of URLs is saved to a file for +persistence and loaded on startup. URLs from the configuration file are +never discarded. + +.. _Usage: + +Usage +----- + +To start HOSTLIST by default, it has to be added to the DEFAULTSERVICES +section for the ARM services. This is done in the default configuration. + +For more information on how to configure the HOSTLIST subsystem see the +installation handbook: Configuring the hostlist to bootstrap Configuring +your peer to provide a hostlist diff --git a/man_developers/subsystems/identity/identity.rst b/man_developers/subsystems/identity/identity.rst @@ -0,0 +1,182 @@ + +.. index:: + double: IDENTITY; subsystem + +.. _IDENTITY-Subsystem: + +IDENTITY — Ego management +========================= + +Identities of \"users\" in GNUnet are called egos. Egos can be used as +pseudonyms (\"fake names\") or be tied to an organization (for example, +\"GNU\") or even the actual identity of a human. GNUnet users are +expected to have many egos. They might have one tied to their real +identity, some for organizations they manage, and more for different +domains where they want to operate under a pseudonym. + +The IDENTITY service allows users to manage their egos. The identity +service manages the private keys egos of the local user; it does not +manage identities of other users (public keys). Public keys for other +users need names to become manageable. GNUnet uses the GNU Name System +(GNS) to give names to other users and manage their public keys +securely. This chapter is about the IDENTITY service, which is about the +management of private keys. + +On the network, an ego corresponds to an ECDSA key (over Curve25519, +using RFC 6979, as required by GNS). Thus, users can perform actions +under a particular ego by using (signing with) a particular private key. +Other users can then confirm that the action was really performed by +that ego by checking the signature against the respective public key. + +The IDENTITY service allows users to associate a human-readable name +with each ego. This way, users can use names that will remind them of +the purpose of a particular ego. The IDENTITY service will store the +respective private keys and allows applications to access key +information by name. Users can change the name that is locally (!) +associated with an ego. Egos can also be deleted, which means that the +private key will be removed and it thus will not be possible to perform +actions with that ego in the future. + +Additionally, the IDENTITY subsystem can associate service functions +with egos. For example, GNS requires the ego that should be used for the +shorten zone. GNS will ask IDENTITY for an ego for the \"gns-short\" +service. The IDENTITY service has a mapping of such service strings to +the name of the ego that the user wants to use for this service, for +example \"my-short-zone-ego\". + +Finally, the IDENTITY API provides access to a special ego, the +anonymous ego. The anonymous ego is special in that its private key is +not really private, but fixed and known to everyone. Thus, anyone can +perform actions as anonymous. This can be useful as with this trick, +code does not have to contain a special case to distinguish between +anonymous and pseudonymous egos. + +:index:`libgnunetidentity <single: libgnunet; identity>` +-------------------------------------------------------- + +.. _Connecting-to-the-service: + +Connecting to the service +^^^^^^^^^^^^^^^^^^^^^^^^^ + +First, typical clients connect to the identity service using +``GNUNET_IDENTITY_connect``. This function takes a callback as a +parameter. If the given callback parameter is non-null, it will be +invoked to notify the application about the current state of the +identities in the system. + +- First, it will be invoked on all known egos at the time of the + connection. For each ego, a handle to the ego and the user's name for + the ego will be passed to the callback. Furthermore, a ``void **`` + context argument will be provided which gives the client the + opportunity to associate some state with the ego. + +- Second, the callback will be invoked with NULL for the ego, the name + and the context. This signals that the (initial) iteration over all + egos has completed. + +- Then, the callback will be invoked whenever something changes about + an ego. If an ego is renamed, the callback is invoked with the ego + handle of the ego that was renamed, and the new name. If an ego is + deleted, the callback is invoked with the ego handle and a name of + NULL. In the deletion case, the application should also release + resources stored in the context. + +- When the application destroys the connection to the identity service + using ``GNUNET_IDENTITY_disconnect``, the callback is again invoked + with the ego and a name of NULL (equivalent to deletion of the egos). + This should again be used to clean up the per-ego context. + +The ego handle passed to the callback remains valid until the callback +is invoked with a name of NULL, so it is safe to store a reference to +the ego's handle. + +.. _Operations-on-Egos: + +Operations on Egos +^^^^^^^^^^^^^^^^^^ + +Given an ego handle, the main operations are to get its associated +private key using ``GNUNET_IDENTITY_ego_get_private_key`` or its +associated public key using ``GNUNET_IDENTITY_ego_get_public_key``. + +The other operations on egos are pretty straightforward. Using +``GNUNET_IDENTITY_create``, an application can request the creation of +an ego by specifying the desired name. The operation will fail if that +name is already in use. Using ``GNUNET_IDENTITY_rename`` the name of an +existing ego can be changed. Finally, egos can be deleted using +``GNUNET_IDENTITY_delete``. All of these operations will trigger updates +to the callback given to the ``GNUNET_IDENTITY_connect`` function of all +applications that are connected with the identity service at the time. +``GNUNET_IDENTITY_cancel`` can be used to cancel the operations before +the respective continuations would be called. It is not guaranteed that +the operation will not be completed anyway, only the continuation will +no longer be called. + +.. _The-anonymous-Ego: + +The anonymous Ego +^^^^^^^^^^^^^^^^^ + +A special way to obtain an ego handle is to call +``GNUNET_IDENTITY_ego_get_anonymous``, which returns an ego for the +\"anonymous\" user --- anyone knows and can get the private key for this +user, so it is suitable for operations that are supposed to be anonymous +but require signatures (for example, to avoid a special path in the +code). The anonymous ego is always valid and accessing it does not +require a connection to the identity service. + +.. _Convenience-API-to-lookup-a-single-ego: + +Convenience API to lookup a single ego +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As applications commonly simply have to lookup a single ego, there is a +convenience API to do just that. Use ``GNUNET_IDENTITY_ego_lookup`` to +lookup a single ego by name. Note that this is the user's name for the +ego, not the service function. The resulting ego will be returned via a +callback and will only be valid during that callback. The operation can +be canceled via ``GNUNET_IDENTITY_ego_lookup_cancel`` (cancellation is +only legal before the callback is invoked). + +.. _Associating-egos-with-service-functions: + +Associating egos with service functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``GNUNET_IDENTITY_set`` function is used to associate a particular +ego with a service function. The name used by the service and the ego +are given as arguments. Afterwards, the service can use its name to +lookup the associated ego using ``GNUNET_IDENTITY_get``. + +.. _The-IDENTITY-Client_002dService-Protocol: + +The IDENTITY Client-Service Protocol +------------------------------------ + +A client connecting to the identity service first sends a message with +type ``GNUNET_MESSAGE_TYPE_IDENTITY_START`` to the service. After that, +the client will receive information about changes to the egos by +receiving messages of type ``GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE``. +Those messages contain the private key of the ego and the user's name of +the ego (or zero bytes for the name to indicate that the ego was +deleted). A special bit ``end_of_list`` is used to indicate the end of +the initial iteration over the identity service's egos. + +The client can trigger changes to the egos by sending ``CREATE``, +``RENAME`` or ``DELETE`` messages. The CREATE message contains the +private key and the desired name. The RENAME message contains the old +name and the new name. The DELETE message only needs to include the name +of the ego to delete. The service responds to each of these messages +with a ``RESULT_CODE`` message which indicates success or error of the +operation, and possibly a human-readable error message. + +Finally, the client can bind the name of a service function to an ego by +sending a ``SET_DEFAULT`` message with the name of the service function +and the private key of the ego. Such bindings can then be resolved using +a ``GET_DEFAULT`` message, which includes the name of the service +function. The identity service will respond to a GET_DEFAULT request +with a SET_DEFAULT message containing the respective information, or +with a RESULT_CODE to indicate an error. + + diff --git a/man_developers/subsystems/index.rst b/man_developers/subsystems/index.rst @@ -0,0 +1,90 @@ + +.. _System-Architecture: + +******************* +System Architecture +******************* + +.. todo:: + FIXME: For those irritated by the textflow, we are missing images here, + in the short term we should add them back, in the long term this should + work without images or have images with alt-text. + +.. todo:: Adjust image sizes so that they are less obtrusive. + +GNUnet developers like LEGOs. The blocks are indestructible, can be +stacked together to construct complex buildings and it is generally easy +to swap one block for a different one that has the same shape. GNUnet's +architecture is based on LEGOs: + +|service_lego_block| + +This chapter documents the GNUnet LEGO system, also known as GNUnet's +system architecture. + +The most common GNUnet component is a service. Services offer an API (or +several, depending on what you count as \"an API\") which is implemented +as a library. The library communicates with the main process of the +service using a service-specific network protocol. The main process of +the service typically doesn't fully provide everything that is needed +--- it has holes to be filled by APIs to other services. + +A special kind of component in GNUnet are user interfaces and daemons. +Like services, they have holes to be filled by APIs of other services. +Unlike services, daemons do not implement their own network protocol and +they have no API: + +|daemon_lego_block| + +The GNUnet system provides a range of services, daemons and user +interfaces, which are then combined into a layered GNUnet instance (also +known as a peer). + +|service_stack| + +Note that while it is generally possible to swap one service for another +compatible service, there is often only one implementation. However, +during development we often have a \"new\" version of a service in +parallel with an \"old\" version. While the \"new\" version is not +working, developers working on other parts of the service can continue +their development by simply using the \"old\" service. Alternative +design ideas can also be easily investigated by swapping out individual +components. This is typically achieved by simply changing the name of +the \"BINARY\" in the respective configuration section. + +Key properties of GNUnet services are that they must be separate +processes and that they must protect themselves by applying tight error +checking against the network protocol they implement (thereby achieving +a certain degree of robustness). + +On the other hand, the APIs are implemented to tolerate failures of the +service, isolating their host process from errors by the service. If the +service process crashes, other services and daemons around it should not +also fail, but instead wait for the service process to be restarted by +ARM. + +.. todo:: + + Missing subsystems: + * TOPOLOGY, FRAGMENTATION + * VPN and support services (DNS, PT, EXIT) + * DATASTORE (only used by FS?) + * MULTICAST and social services (PSYC, PSYCSTORE, SOCIAL) + * GNS support services/applications (GNSRECORD, ZONEMASTER) + * Set-based applications (SCALARPRODUCT, SECRETSHARING, CONSENSUS, VOTING) + +.. toctree:: + :maxdepth: 2 + + deps.rst + stability.rst + + corestack.rst + setops.rst + vpnstack.rst + gnsstack.rst + apps.rst + +.. |service_lego_block| image:: /_static/images/service_lego_block.png +.. |daemon_lego_block| image:: /_static/images/daemon_lego_block.png +.. |service_stack| image:: /_static/images/service_stack.png diff --git a/man_developers/subsystems/messenger/messenger.rst b/man_developers/subsystems/messenger/messenger.rst @@ -0,0 +1,240 @@ +.. index:: + double: subsystem; MESSENGER + +.. _MESSENGER-Subsystem: + +MESSENGER — Room-based end-to-end messaging +=========================================== + +The MESSENGER subsystem is responsible for secure end-to-end +communication in groups of nodes in the GNUnet overlay network. +MESSENGER builds on the CADET subsystem which provides a reliable and +secure end-to-end communication between the nodes inside of these +groups. + +Additionally to the CADET security benefits, MESSENGER provides +following properties designed for application level usage: + +- MESSENGER provides integrity by signing the messages with the users + provided ego + +- MESSENGER adds (optional) forward secrecy by replacing the key pair + of the used ego and signing the propagation of the new one with old + one (chaining egos) + +- MESSENGER provides verification of a original sender by checking + against all used egos from a member which are currently in active use + (active use depends on the state of a member session) + +- MESSENGER offsers (optional) decentralized message forwarding between + all nodes in a group to improve availability and prevent MITM-attacks + +- MESSENGER handles new connections and disconnections from nodes in + the group by reconnecting them preserving an efficient structure for + message distribution (ensuring availability and accountablity) + +- MESSENGER provides replay protection (messages can be uniquely + identified via SHA-512, include a timestamp and the hash of the last + message) + +- MESSENGER allows detection for dropped messages by chaining them + (messages refer to the last message by their hash) improving + accountability + +- MESSENGER allows requesting messages from other peers explicitly to + ensure availability + +- MESSENGER provides confidentiality by padding messages to few + different sizes (512 bytes, 4096 bytes, 32768 bytes and maximal + message size from CADET) + +- MESSENGER adds (optional) confidentiality with ECDHE to exchange and + use symmetric encryption, encrypting with both AES-256 and Twofish + but allowing only selected members to decrypt (using the receivers + ego for ECDHE) + +Also MESSENGER provides multiple features with privacy in mind: + +- MESSENGER allows deleting messages from all peers in the group by the + original sender (uses the MESSENGER provided verification) + +- MESSENGER allows using the publicly known anonymous ego instead of + any unique identifying ego + +- MESSENGER allows your node to decide between acting as host of the + used messaging room (sharing your peer's identity with all nodes in + the group) or acting as guest (sharing your peer's identity only with + the nodes you explicitly open a connection to) + +- MESSENGER handles members independently of the peer's identity making + forwarded messages indistinguishable from directly received ones ( + complicating the tracking of messages and identifying its origin) + +- MESSENGER allows names of members being not unique (also names are + optional) + +- MESSENGER does not include information about the selected receiver of + an explicitly encrypted message in its header, complicating it for + other members to draw conclusions from communication partners + + +:index:`libgnunetmessenger <single: libgnunet; messenger>` +---------------------------------------------------------- + +The MESSENGER API (defined in ``gnunet_messenger_service.h``) allows P2P +applications built using GNUnet to communicate with specified kinds of +messages in a group. It provides applications the ability to send and +receive encrypted messages to any group of peers participating in GNUnet +in a decentralized way ( without even knowing all peers's identities). + +MESSENGER delivers messages to other peers in \"rooms\". A room uses a +variable amount of CADET \"channels\" which will all be used for message +distribution. Each channel can represent an outgoing connection opened +by entering a room with ``GNUNET_MESSENGER_enter_room`` or an incoming +connection if the room was opened before via +``GNUNET_MESSENGER_open_room``. + +|messenger_room| + +To enter a room you have to specify the \"door\" (peer's identity of a +peer which has opened the room) and the key of the room (which is +identical to a CADET \"port\"). To open a room you have to specify only +the key to use. When opening a room you automatically distribute a +PEER-message sharing your peer's identity in the room. + +Entering or opening a room can also be combined in any order. In any +case you will automatically get a unique member ID and send a +JOIN-message notifying others about your entry and your public key from +your selected ego. + +The ego can be selected by name with the initial +``GNUNET_MESSENGER_connect`` besides setting a (identity-)callback for +each change/confirmation of the used ego and a (message-)callback which +gets called every time a message gets sent or received in the room. Once +the identity-callback got called you can check your used ego with +``GNUNET_MESSENGER_get_key`` providing only its public key. The function +returns NULL if the anonymous ego is used. If the ego should be replaced +with a newly generated one, you can use ``GNUNET_MESSENGER_update`` to +ensure proper chaining of used egos. + +Also once the identity-callback got called you can check your used name +with ``GNUNET_MESSENGER_get_name`` and potentially change or set a name +via ``GNUNET_MESSENGER_set_name``. A name is for example required to +create a new ego with ``GNUNET_MESSENGER_update``. Also any change in +ego or name will automatically be distributed in the room with a NAME- +or KEY-message respectively. + +To send a message a message inside of a room you can use +``GNUNET_MESSENGER_send_message``. If you specify a selected contact as +receiver, the message gets encrypted automatically and will be sent as +PRIVATE- message instead. + +To request a potentially missed message or to get a specific message +after its original call of the message-callback, you can use +``GNUNET_MESSENGER_get_message``. Additionally once a message was +distributed to application level and the message-callback got called, +you can get the contact respresenting a message's sender respectively +with ``GNUNET_MESSENGER_get_sender``. This allows getting name and the +public key of any sender currently in use with +``GNUNET_MESSENGER_contact_get_name`` and +``GNUNET_MESSENGER_contact_get_key``. It is also possible to iterate +through all current members of a room with +``GNUNET_MESSENGER_iterate_members`` using a callback. + +To leave a room you can use ``GNUNET_MESSENGER_close_room`` which will +also close the rooms connections once all applications on the same peer +have left the room. Leaving a room will also send a LEAVE-message +closing a member session on all connected peers before any connection +will be closed. Leaving a room is however not required for any +application to keep your member session open between multiple sessions +of the actual application. + +Finally, when an application no longer wants to use CADET, it should +call ``GNUNET_MESSENGER_disconnect``. You don't have to explicitly close +the used rooms or leave them. + +Here is a little summary to the kinds of messages you can send manually: + +.. _MERGE_002dmessage: + +MERGE-message +^^^^^^^^^^^^^ + +MERGE-messages will generally be sent automatically to reduce the amount +of parallel chained messages. This is necessary to close a member +session for example. You can also send MERGE-messages manually if +required to merge two chains of messages. + +.. _INVITE_002dmessage: + +INVITE-message +^^^^^^^^^^^^^^ + +INVITE-messages can be used to invite other members in a room to a +different room, sharing one potential door and the required key to enter +the room. This kind of message is typically sent as encrypted +PRIVATE-message to selected members because it doesn't make much sense +to invite all members from one room to another considering a rooms key +doesn't specify its usage. + +.. _TEXT_002dmessage: + +TEXT-message +^^^^^^^^^^^^ + +TEXT-messages can be used to send simple text-based messages and should +be considered as being in readable form without complex decoding. The +text has to end with a NULL-terminator character and should be in UTF-8 +encoding for most compatibility. + +.. _FILE_002dmessage: + +FILE-message +^^^^^^^^^^^^ + +FILE-messages can be used to share files inside of a room. They do not +contain the actual file being shared but its original hash, filename, +URI to download the file and a symmetric key to decrypt the downloaded +file. + +It is recommended to use the FS subsystem and the FILE-messages in +combination. + +.. _DELETE_002dmessage: + +DELETE-message +^^^^^^^^^^^^^^ + +DELETE-messages can be used to delete messages selected with its hash. +You can also select any custom delay relative to the time of sending the +DELETE-message. Deletion will only be processed on each peer in a room +if the sender is authorized. + +The only information of a deleted message which being kept will be the +chained hashes connecting the message graph for potential traversion. +For example the check for completion of a member session requires this +information. + +.. _Member-sessions: + +Member sessions +--------------- + +A member session is a triple of the room key, the member ID and the +public key of the member's ego. Member sessions allow that a member can +change their ID or their ego once at a time without losing the ability +to delete old messages or identifying the original sender of a message. +On every change of ID or EGO a session will be marked as closed. So +every session chain will only contain one open session with the current +ID and public key. + +If a session is marked as closed the MESSENGER service will check from +the first message opening a session to its last one closing the session +for completion. If a the service can confirm that there is no message +still missing which was sent from the closed member session, it will be +marked as completed. + +A completed member session is not able to verify any incoming message to +ensure forward secrecy preventing others from using old stolen egos. + +.. |messenger_room| image:: /_static/images/messenger_room.png diff --git a/man_developers/subsystems/namecache/namecache.rst b/man_developers/subsystems/namecache/namecache.rst @@ -0,0 +1,127 @@ + +.. index:: + single: GNS; name cache + double: subsystem; NAMECACHE + +.. _GNS-Namecache: + +NAMECACHE — DHT caching of GNS results +====================================== + +The NAMECACHE subsystem is responsible for caching (encrypted) +resolution results of the GNU Name System (GNS). GNS makes zone +information available to other users via the DHT. However, as accessing +the DHT for every lookup is expensive (and as the DHT's local cache is +lost whenever the peer is restarted), GNS uses the NAMECACHE as a more +persistent cache for DHT lookups. Thus, instead of always looking up +every name in the DHT, GNS first checks if the result is already +available locally in the NAMECACHE. Only if there is no result in the +NAMECACHE, GNS queries the DHT. The NAMECACHE stores data in the same +(encrypted) format as the DHT. It thus makes no sense to iterate over +all items in the NAMECACHE – the NAMECACHE does not have a way to +provide the keys required to decrypt the entries. + +Blocks in the NAMECACHE share the same expiration mechanism as blocks in +the DHT – the block expires wheneever any of the records in the +(encrypted) block expires. The expiration time of the block is the only +information stored in plaintext. The NAMECACHE service internally +performs all of the required work to expire blocks, clients do not have +to worry about this. Also, given that NAMECACHE stores only GNS blocks +that local users requested, there is no configuration option to limit +the size of the NAMECACHE. It is assumed to be always small enough (a +few MB) to fit on the drive. + +The NAMECACHE supports the use of different database backends via a +plugin API. + +:index:`libgnunetnamecache <single: libgnunet; namecache>` +---------------------------------------------------------- + +The NAMECACHE API consists of five simple functions. First, there is +``GNUNET_NAMECACHE_connect`` to connect to the NAMECACHE service. This +returns the handle required for all other operations on the NAMECACHE. +Using ``GNUNET_NAMECACHE_block_cache`` clients can insert a block into +the cache. ``GNUNET_NAMECACHE_lookup_block`` can be used to lookup +blocks that were stored in the NAMECACHE. Both operations can be +canceled using ``GNUNET_NAMECACHE_cancel``. Note that canceling a +``GNUNET_NAMECACHE_block_cache`` operation can result in the block being +stored in the NAMECACHE --- or not. Cancellation primarily ensures that +the continuation function with the result of the operation will no +longer be invoked. Finally, ``GNUNET_NAMECACHE_disconnect`` closes the +connection to the NAMECACHE. + +The maximum size of a block that can be stored in the NAMECACHE is +``GNUNET_NAMECACHE_MAX_VALUE_SIZE``, which is defined to be 63 kB. + +.. _The-NAMECACHE-Client_002dService-Protocol: + +The NAMECACHE Client-Service Protocol +------------------------------------- + +All messages in the NAMECACHE IPC protocol start with the +``struct GNUNET_NAMECACHE_Header`` which adds a request ID (32-bit +integer) to the standard message header. The request ID is used to match +requests with the respective responses from the NAMECACHE, as they are +allowed to happen out-of-order. + +.. _Lookup: + +Lookup +^^^^^^ + +The ``struct LookupBlockMessage`` is used to lookup a block stored in +the cache. It contains the query hash. The NAMECACHE always responds +with a ``struct LookupBlockResponseMessage``. If the NAMECACHE has no +response, it sets the expiration time in the response to zero. +Otherwise, the response is expected to contain the expiration time, the +ECDSA signature, the derived key and the (variable-size) encrypted data +of the block. + +.. _Store: + +Store +^^^^^ + +The ``struct BlockCacheMessage`` is used to cache a block in the +NAMECACHE. It has the same structure as the +``struct LookupBlockResponseMessage``. The service responds with a +``struct BlockCacheResponseMessage`` which contains the result of the +operation (success or failure). In the future, we might want to make it +possible to provide an error message as well. + +.. _The-NAMECACHE-Plugin-API: + +The NAMECACHE Plugin API +------------------------ + +The NAMECACHE plugin API consists of two functions, ``cache_block`` to +store a block in the database, and ``lookup_block`` to lookup a block in +the database. + +.. _Lookup2: + +Lookup2 +^^^^^^^ + +The ``lookup_block`` function is expected to return at most one block to +the iterator, and return ``GNUNET_NO`` if there were no non-expired +results. If there are multiple non-expired results in the cache, the +lookup is supposed to return the result with the largest expiration +time. + +.. _Store2: + +Store2 +^^^^^^ + +The ``cache_block`` function is expected to try to store the block in +the database, and return ``GNUNET_SYSERR`` if this was not possible for +any reason. Furthermore, ``cache_block`` is expected to implicitly +perform cache maintenance and purge blocks from the cache that have +expired. Note that ``cache_block`` might encounter the case where the +database already has another block stored under the same key. In this +case, the plugin must ensure that the block with the larger expiration +time is preserved. Obviously, this can done either by simply adding new +blocks and selecting for the most recent expiration time during lookup, +or by checking which block is more recent during the store operation. + diff --git a/man_developers/subsystems/namestore/namestore.rst b/man_developers/subsystems/namestore/namestore.rst @@ -0,0 +1,126 @@ + +.. index:: + double: subsystem; NAMESTORE + +.. _NAMESTORE-Subsystem: + +NAMESTORE — Storage of local GNS zones +====================================== + +The NAMESTORE subsystem provides persistent storage for local GNS zone +information. All local GNS zone information are managed by NAMESTORE. It +provides both the functionality to administer local GNS information +(e.g. delete and add records) as well as to retrieve GNS information +(e.g to list name information in a client). NAMESTORE does only manage +the persistent storage of zone information belonging to the user running +the service: GNS information from other users obtained from the DHT are +stored by the NAMECACHE subsystem. + +NAMESTORE uses a plugin-based database backend to store GNS information +with good performance. Here sqlite, MySQL and PostgreSQL are supported +database backends. NAMESTORE clients interact with the IDENTITY +subsystem to obtain cryptographic information about zones based on egos +as described with the IDENTITY subsystem, but internally NAMESTORE +refers to zones using the ECDSA private key. In addition, it +collaborates with the NAMECACHE subsystem and stores zone information +when local information are modified in the GNS cache to increase look-up +performance for local information. + +NAMESTORE provides functionality to look-up and store records, to +iterate over a specific or all zones and to monitor zones for changes. +NAMESTORE functionality can be accessed using the NAMESTORE api or the +NAMESTORE command line tool. + +:index:`libgnunetnamestore <single: libgnunet; namestore>` +---------------------------------------------------------- + +To interact with NAMESTORE clients first connect to the NAMESTORE +service using the ``GNUNET_NAMESTORE_connect`` passing a configuration +handle. As a result they obtain a NAMESTORE handle, they can use for +operations, or NULL is returned if the connection failed. + +To disconnect from NAMESTORE, clients use +``GNUNET_NAMESTORE_disconnect`` and specify the handle to disconnect. + +NAMESTORE internally uses the ECDSA private key to refer to zones. These +private keys can be obtained from the IDENTITY subsystem. Here *egos* +*can be used to refer to zones or the default ego assigned to the GNS +subsystem can be used to obtained the master zone's private key.* + +.. _Editing-Zone-Information: + +Editing Zone Information +^^^^^^^^^^^^^^^^^^^^^^^^ + +NAMESTORE provides functions to lookup records stored under a label in a +zone and to store records under a label in a zone. + +To store (and delete) records, the client uses the +``GNUNET_NAMESTORE_records_store`` function and has to provide namestore +handle to use, the private key of the zone, the label to store the +records under, the records and number of records plus an callback +function. After the operation is performed NAMESTORE will call the +provided callback function with the result GNUNET_SYSERR on failure +(including timeout/queue drop/failure to validate), GNUNET_NO if content +was already there or not found GNUNET_YES (or other positive value) on +success plus an additional error message. + +Records are deleted by using the store command with 0 records to store. +It is important to note, that records are not merged when records exist +with the label. So a client has first to retrieve records, merge with +existing records and then store the result. + +To perform a lookup operation, the client uses the +``GNUNET_NAMESTORE_records_store`` function. Here it has to pass the +namestore handle, the private key of the zone and the label. It also has +to provide a callback function which will be called with the result of +the lookup operation: the zone for the records, the label, and the +records including the number of records included. + +A special operation is used to set the preferred nickname for a zone. +This nickname is stored with the zone and is automatically merged with +all labels and records stored in a zone. Here the client uses the +``GNUNET_NAMESTORE_set_nick`` function and passes the private key of the +zone, the nickname as string plus a the callback with the result of the +operation. + +.. _Iterating-Zone-Information: + +Iterating Zone Information +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A client can iterate over all information in a zone or all zones managed +by NAMESTORE. Here a client uses the +``GNUNET_NAMESTORE_zone_iteration_start`` function and passes the +namestore handle, the zone to iterate over and a callback function to +call with the result. To iterate over all the zones, it is possible to +pass NULL for the zone. A ``GNUNET_NAMESTORE_ZoneIterator`` handle is +returned to be used to continue iteration. + +NAMESTORE calls the callback for every result and expects the client to +call ``GNUNET_NAMESTORE_zone_iterator_next`` to continue to iterate or +``GNUNET_NAMESTORE_zone_iterator_stop`` to interrupt the iteration. When +NAMESTORE reached the last item it will call the callback with a NULL +value to indicate. + +.. _Monitoring-Zone-Information: + +Monitoring Zone Information +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Clients can also monitor zones to be notified about changes. Here the +clients uses the ``GNUNET_NAMESTORE_zone_monitor_start`` function and +passes the private key of the zone and and a callback function to call +with updates for a zone. The client can specify to obtain zone +information first by iterating over the zone and specify a +synchronization callback to be called when the client and the namestore +are synced. + +On an update, NAMESTORE will call the callback with the private key of +the zone, the label and the records and their number. + +To stop monitoring, the client calls +``GNUNET_NAMESTORE_zone_monitor_stop`` and passes the handle obtained +from the function to start the monitoring. + + diff --git a/man_developers/subsystems/nse/nse.rst b/man_developers/subsystems/nse/nse.rst @@ -0,0 +1,312 @@ +.. index:: + single: subsystem; Network size estimation + see: NSE; Network size estimation + +.. _NSE-Subsystem: + +NSE — Network size estimation +============================= + +NSE stands for Network Size Estimation. The NSE subsystem provides other +subsystems and users with a rough estimate of the number of peers +currently participating in the GNUnet overlay. The computed value is not +a precise number as producing a precise number in a decentralized, +efficient and secure way is impossible. While NSE's estimate is +inherently imprecise, NSE also gives the expected range. For a peer that +has been running in a stable network for a while, the real network size +will typically (99.7% of the time) be in the range of [2/3 estimate, 3/2 +estimate]. We will now give an overview of the algorithm used to +calculate the estimate; all of the details can be found in this +technical report. + +.. todo:: link to the report. + +.. _Motivation: + +Motivation +---------- + +Some subsystems, like DHT, need to know the size of the GNUnet network +to optimize some parameters of their own protocol. The decentralized +nature of GNUnet makes efficient and securely counting the exact number +of peers infeasible. Although there are several decentralized algorithms +to count the number of peers in a system, so far there is none to do so +securely. Other protocols may allow any malicious peer to manipulate the +final result or to take advantage of the system to perform Denial of +Service (DoS) attacks against the network. GNUnet's NSE protocol avoids +these drawbacks. + +NSE security +.. _Security: + +:index:`Security <single: NSE; security>` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The NSE subsystem is designed to be resilient against these attacks. It +uses `proofs of +work <http://en.wikipedia.org/wiki/Proof-of-work_system>`__ to prevent +one peer from impersonating a large number of participants, which would +otherwise allow an adversary to artificially inflate the estimate. The +DoS protection comes from the time-based nature of the protocol: the +estimates are calculated periodically and out-of-time traffic is either +ignored or stored for later retransmission by benign peers. In +particular, peers cannot trigger global network communication at will. + +.. _Principle: + +:index:`Principle <single: NSE; principle of operation>` +-------------------------------------------------------- + +The algorithm calculates the estimate by finding the globally closest +peer ID to a random, time-based value. + +The idea is that the closer the ID is to the random value, the more +\"densely packed\" the ID space is, and therefore, more peers are in the +network. + +.. _Example: + +Example +^^^^^^^ + +Suppose all peers have IDs between 0 and 100 (our ID space), and the +random value is 42. If the closest peer has the ID 70 we can imagine +that the average \"distance\" between peers is around 30 and therefore +the are around 3 peers in the whole ID space. On the other hand, if the +closest peer has the ID 44, we can imagine that the space is rather +packed with peers, maybe as much as 50 of them. Naturally, we could have +been rather unlucky, and there is only one peer and happens to have the +ID 44. Thus, the current estimate is calculated as the average over +multiple rounds, and not just a single sample. + +.. _Algorithm: + +Algorithm +^^^^^^^^^ + +Given that example, one can imagine that the job of the subsystem is to +efficiently communicate the ID of the closest peer to the target value +to all the other peers, who will calculate the estimate from it. + +.. _Target-value: + +Target value +^^^^^^^^^^^^ + +The target value itself is generated by hashing the current time, +rounded down to an agreed value. If the rounding amount is 1h (default) +and the time is 12:34:56, the time to hash would be 12:00:00. The +process is repeated each rounding amount (in this example would be every +hour). Every repetition is called a round. + +.. _Timing: + +Timing +^^^^^^ + +The NSE subsystem has some timing control to avoid everybody +broadcasting its ID all at one. Once each peer has the target random +value, it compares its own ID to the target and calculates the +hypothetical size of the network if that peer were to be the closest. +Then it compares the hypothetical size with the estimate from the +previous rounds. For each value there is an associated point in the +period, let's call it \"broadcast time\". If its own hypothetical +estimate is the same as the previous global estimate, its \"broadcast +time\" will be in the middle of the round. If its bigger it will be +earlier and if its smaller (the most likely case) it will be later. This +ensures that the peers closest to the target value start broadcasting +their ID the first. + +.. _Controlled-Flooding: + +Controlled Flooding +^^^^^^^^^^^^^^^^^^^ + +When a peer receives a value, first it verifies that it is closer than +the closest value it had so far, otherwise it answers the incoming +message with a message containing the better value. Then it checks a +proof of work that must be included in the incoming message, to ensure +that the other peer's ID is not made up (otherwise a malicious peer +could claim to have an ID of exactly the target value every round). Once +validated, it compares the broadcast time of the received value with the +current time and if it's not too early, sends the received value to its +neighbors. Otherwise it stores the value until the correct broadcast +time comes. This prevents unnecessary traffic of sub-optimal values, +since a better value can come before the broadcast time, rendering the +previous one obsolete and saving the traffic that would have been used +to broadcast it to the neighbors. + +.. _Calculating-the-estimate: + +Calculating the estimate +^^^^^^^^^^^^^^^^^^^^^^^^ + +Once the closest ID has been spread across the network each peer gets +the exact distance between this ID and the target value of the round and +calculates the estimate with a mathematical formula described in the +tech report. The estimate generated with this method for a single round +is not very precise. Remember the case of the example, where the only +peer is the ID 44 and we happen to generate the target value 42, +thinking there are 50 peers in the network. Therefore, the NSE subsystem +remembers the last 64 estimates and calculates an average over them, +giving a result of which usually has one bit of uncertainty (the real +size could be half of the estimate or twice as much). Note that the +actual network size is calculated in powers of two of the raw input, +thus one bit of uncertainty means a factor of two in the size estimate. + +:index:`libgnunetnse <single: libgnunet; nse>` +---------------------------------------------- + +The NSE subsystem has the simplest API of all services, with only two +calls: ``GNUNET_NSE_connect`` and ``GNUNET_NSE_disconnect``. + +The connect call gets a callback function as a parameter and this +function is called each time the network agrees on an estimate. This +usually is once per round, with some exceptions: if the closest peer has +a late local clock and starts spreading its ID after everyone else +agreed on a value, the callback might be activated twice in a round, the +second value being always bigger than the first. The default round time +is set to 1 hour. + +The disconnect call disconnects from the NSE subsystem and the callback +is no longer called with new estimates. + +.. _Results: + +Results +^^^^^^^ + +The callback provides two values: the average and the `standard +deviation <http://en.wikipedia.org/wiki/Standard_deviation>`__ of the +last 64 rounds. The values provided by the callback function are +logarithmic, this means that the real estimate numbers can be obtained +by calculating 2 to the power of the given value (2average). From a +statistics point of view this means that: + +- 68% of the time the real size is included in the interval + [(2average-stddev), 2] + +- 95% of the time the real size is included in the interval + [(2average-2*stddev, 2^average+2*stddev] + +- 99.7% of the time the real size is included in the interval + [(2average-3*stddev, 2average+3*stddev] + +The expected standard variation for 64 rounds in a network of stable +size is 0.2. Thus, we can say that normally: + +- 68% of the time the real size is in the range [-13%, +15%] + +- 95% of the time the real size is in the range [-24%, +32%] + +- 99.7% of the time the real size is in the range [-34%, +52%] + +As said in the introduction, we can be quite sure that usually the real +size is between one third and three times the estimate. This can of +course vary with network conditions. Thus, applications may want to also +consider the provided standard deviation value, not only the average (in +particular, if the standard variation is very high, the average maybe +meaningless: the network size is changing rapidly). + +.. _libgnunetnse-_002d-Examples: + +Examples +^^^^^^^^ + +Let's close with a couple examples. + +Average: 10, std dev: 1 Here the estimate would be + 2^10 = 1024 peers. (The range in which we can be 95% sure is: [2^8, + 2^12] = [256, 4096]. We can be very (>99.7%) sure that the network is + not a hundred peers and absolutely sure that it is not a million + peers, but somewhere around a thousand.) + +Average 22, std dev: 0.2 Here the estimate would be + 2^22 = 4 Million peers. (The range in which we can be 99.7% sure is: + [2^21.4, 2^22.6] = [2.8M, 6.3M]. We can be sure that the network size + is around four million, with absolutely way of it being 1 million.) + +To put this in perspective, if someone remembers the LHC Higgs boson +results, were announced with \"5 sigma\" and \"6 sigma\" certainties. In +this case a 5 sigma minimum would be 2 million and a 6 sigma minimum, +1.8 million. + +.. _The-NSE-Client_002dService-Protocol: + +The NSE Client-Service Protocol +------------------------------- + +As with the API, the client-service protocol is very simple, only has 2 +different messages, defined in ``src/nse/nse.h``: + +- ``GNUNET_MESSAGE_TYPE_NSE_START`` This message has no parameters and + is sent from the client to the service upon connection. + +- ``GNUNET_MESSAGE_TYPE_NSE_ESTIMATE`` This message is sent from the + service to the client for every new estimate and upon connection. + Contains a timestamp for the estimate, the average and the standard + deviation for the respective round. + +When the ``GNUNET_NSE_disconnect`` API call is executed, the client +simply disconnects from the service, with no message involved. + +NSE Peer-to-Peer Protocol +.. _The-NSE-Peer_002dto_002dPeer-Protocol: + +The NSE Peer-to-Peer Protocol +----------------------------- + +GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD +The NSE subsystem only has one message in the P2P protocol, the +``GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD`` message. + +This message key contents are the timestamp to identify the round +(differences in system clocks may cause some peers to send messages way +too early or way too late, so the timestamp allows other peers to +identify such messages easily), the `proof of +work <http://en.wikipedia.org/wiki/Proof-of-work_system>`__ used to make +it difficult to mount a `Sybil +attack <http://en.wikipedia.org/wiki/Sybil_attack>`__, and the public +key, which is used to verify the signature on the message. + +Every peer stores a message for the previous, current and next round. +The messages for the previous and current round are given to peers that +connect to us. The message for the next round is simply stored until our +system clock advances to the next round. The message for the current +round is what we are flooding the network with right now. At the +beginning of each round the peer does the following: + +- calculates its own distance to the target value + +- creates, signs and stores the message for the current round (unless + it has a better message in the \"next round\" slot which came early + in the previous round) + +- calculates, based on the stored round message (own or received) when + to start flooding it to its neighbors + +Upon receiving a message the peer checks the validity of the message +(round, proof of work, signature). The next action depends on the +contents of the incoming message: + +- if the message is worse than the current stored message, the peer + sends the current message back immediately, to stop the other peer + from spreading suboptimal results + +- if the message is better than the current stored message, the peer + stores the new message and calculates the new target time to start + spreading it to its neighbors (excluding the one the message came + from) + +- if the message is for the previous round, it is compared to the + message stored in the \"previous round slot\", which may then be + updated + +- if the message is for the next round, it is compared to the message + stored in the \"next round slot\", which again may then be updated + +Finally, when it comes to send the stored message for the current round +to the neighbors there is a random delay added for each neighbor, to +avoid traffic spikes and minimize cross-messages. + + diff --git a/man_developers/subsystems/peerinfo/peerinfo.rst b/man_developers/subsystems/peerinfo/peerinfo.rst @@ -0,0 +1,216 @@ + +.. index:: + double: subsystem; PEERINFO + +.. _PEERINFO-Subsystem: + +PEERINFO — Persistent HELLO storage +=================================== + +The PEERINFO subsystem is used to store verified (validated) information +about known peers in a persistent way. It obtains these addresses for +example from TRANSPORT service which is in charge of address validation. +Validation means that the information in the HELLO message are checked +by connecting to the addresses and performing a cryptographic handshake +to authenticate the peer instance stating to be reachable with these +addresses. Peerinfo does not validate the HELLO messages itself but only +stores them and gives them to interested clients. + +As future work, we think about moving from storing just HELLO messages +to providing a generic persistent per-peer information store. More and +more subsystems tend to need to store per-peer information in persistent +way. To not duplicate this functionality we plan to provide a PEERSTORE +service providing this functionality. + +.. _PEERINFO-_002d-Features: + +PEERINFO - Features +------------------- + +- Persistent storage + +- Client notification mechanism on update + +- Periodic clean up for expired information + +- Differentiation between public and friend-only HELLO + +.. _PEERINFO-_002d-Limitations: + +PEERINFO - Limitations +---------------------- + +- Does not perform HELLO validation + +.. _DeveloperPeer-Information: + +DeveloperPeer Information +------------------------- + +The PEERINFO subsystem stores these information in the form of HELLO +messages you can think of as business cards. These HELLO messages +contain the public key of a peer and the addresses a peer can be reached +under. The addresses include an expiration date describing how long they +are valid. This information is updated regularly by the TRANSPORT +service by revalidating the address. If an address is expired and not +renewed, it can be removed from the HELLO message. + +Some peer do not want to have their HELLO messages distributed to other +peers, especially when GNUnet's friend-to-friend modus is enabled. To +prevent this undesired distribution. PEERINFO distinguishes between +*public* and *friend-only* HELLO messages. Public HELLO messages can be +freely distributed to other (possibly unknown) peers (for example using +the hostlist, gossiping, broadcasting), whereas friend-only HELLO +messages may not be distributed to other peers. Friend-only HELLO +messages have an additional flag ``friend_only`` set internally. For +public HELLO message this flag is not set. PEERINFO does and cannot not +check if a client is allowed to obtain a specific HELLO type. + +The HELLO messages can be managed using the GNUnet HELLO library. Other +GNUnet systems can obtain these information from PEERINFO and use it for +their purposes. Clients are for example the HOSTLIST component providing +these information to other peers in form of a hostlist or the TRANSPORT +subsystem using these information to maintain connections to other +peers. + +.. _Startup: + +Startup +------- + +During startup the PEERINFO services loads persistent HELLOs from disk. +First PEERINFO parses the directory configured in the HOSTS value of the +``PEERINFO`` configuration section to store PEERINFO information. For +all files found in this directory valid HELLO messages are extracted. In +addition it loads HELLO messages shipped with the GNUnet distribution. +These HELLOs are used to simplify network bootstrapping by providing +valid peer information with the distribution. The use of these HELLOs +can be prevented by setting the ``USE_INCLUDED_HELLOS`` in the +``PEERINFO`` configuration section to ``NO``. Files containing invalid +information are removed. + +.. _Managing-Information: + +Managing Information +-------------------- + +The PEERINFO services stores information about known PEERS and a single +HELLO message for every peer. A peer does not need to have a HELLO if no +information are available. HELLO information from different sources, for +example a HELLO obtained from a remote HOSTLIST and a second HELLO +stored on disk, are combined and merged into one single HELLO message +per peer which will be given to clients. During this merge process the +HELLO is immediately written to disk to ensure persistence. + +PEERINFO in addition periodically scans the directory where information +are stored for empty HELLO messages with expired TRANSPORT addresses. +This periodic task scans all files in the directory and recreates the +HELLO messages it finds. Expired TRANSPORT addresses are removed from +the HELLO and if the HELLO does not contain any valid addresses, it is +discarded and removed from the disk. + +.. _Obtaining-Information: + +Obtaining Information +--------------------- + +When a client requests information from PEERINFO, PEERINFO performs a +lookup for the respective peer or all peers if desired and transmits +this information to the client. The client can specify if friend-only +HELLOs have to be included or not and PEERINFO filters the respective +HELLO messages before transmitting information. + +To notify clients about changes to PEERINFO information, PEERINFO +maintains a list of clients interested in this notifications. Such a +notification occurs if a HELLO for a peer was updated (due to a merge +for example) or a new peer was added. + +.. _The-PEERINFO-Client_002dService-Protocol: + +The PEERINFO Client-Service Protocol +------------------------------------ + +To connect and disconnect to and from the PEERINFO Service PEERINFO +utilizes the util client/server infrastructure, so no special messages +types are used here. + +To add information for a peer, the plain HELLO message is transmitted to +the service without any wrapping. All pieces of information required are +stored within the HELLO message. The PEERINFO service provides a message +handler accepting and processing these HELLO messages. + +When obtaining PEERINFO information using the iterate functionality +specific messages are used. To obtain information for all peers, a +``struct ListAllPeersMessage`` with message type +``GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL`` and a flag include_friend_only +to indicate if friend-only HELLO messages should be included are +transmitted. If information for a specific peer is required a +``struct ListAllPeersMessage`` with ``GNUNET_MESSAGE_TYPE_PEERINFO_GET`` +containing the peer identity is used. + +For both variants the PEERINFO service replies for each HELLO message it +wants to transmit with a ``struct ListAllPeersMessage`` with type +``GNUNET_MESSAGE_TYPE_PEERINFO_INFO`` containing the plain HELLO. The +final message is ``struct GNUNET_MessageHeader`` with type +``GNUNET_MESSAGE_TYPE_PEERINFO_INFO``. If the client receives this +message, it can proceed with the next request if any is pending. + +:index:`libgnunetpeerinfo <single: libgnunet; peerinfo>` +-------------------------------------------------------- + +The PEERINFO API consists mainly of three different functionalities: + +- maintaining a connection to the service + +- adding new information to the PEERINFO service + +- retrieving information from the PEERINFO service + +.. _Connecting-to-the-PEERINFO-Service: + +Connecting to the PEERINFO Service +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To connect to the PEERINFO service the function +``GNUNET_PEERINFO_connect`` is used, taking a configuration handle as an +argument, and to disconnect from PEERINFO the function +``GNUNET_PEERINFO_disconnect``, taking the PEERINFO handle returned from +the connect function has to be called. + +.. _Adding-Information-to-the-PEERINFO-Service: + +Adding Information to the PEERINFO Service +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``GNUNET_PEERINFO_add_peer`` adds a new peer to the PEERINFO subsystem +storage. This function takes the PEERINFO handle as an argument, the +HELLO message to store and a continuation with a closure to be called +with the result of the operation. The ``GNUNET_PEERINFO_add_peer`` +returns a handle to this operation allowing to cancel the operation with +the respective cancel function ``GNUNET_PEERINFO_add_peer_cancel``. To +retrieve information from PEERINFO you can iterate over all information +stored with PEERINFO or you can tell PEERINFO to notify if new peer +information are available. + +.. _Obtaining-Information-from-the-PEERINFO-Service: + +Obtaining Information from the PEERINFO Service +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To iterate over information in PEERINFO you use +``GNUNET_PEERINFO_iterate``. This function expects the PEERINFO handle, +a flag if HELLO messages intended for friend only mode should be +included, a timeout how long the operation should take and a callback +with a callback closure to be called for the results. If you want to +obtain information for a specific peer, you can specify the peer +identity, if this identity is NULL, information for all peers are +returned. The function returns a handle to allow to cancel the operation +using ``GNUNET_PEERINFO_iterate_cancel``. + +To get notified when peer information changes, you can use +``GNUNET_PEERINFO_notify``. This function expects a configuration handle +and a flag if friend-only HELLO messages should be included. The +PEERINFO service will notify you about every change and the callback +function will be called to notify you about changes. The function +returns a handle to cancel notifications with +``GNUNET_PEERINFO_notify_cancel``. diff --git a/man_developers/subsystems/peerstore/peerstore.rst b/man_developers/subsystems/peerstore/peerstore.rst @@ -0,0 +1,109 @@ + +.. index:: + double: subsystem; PEERSTORE + +.. _PEERSTORE-Subsystem: + +PEERSTORE — Extensible local persistent data storage +==================================================== + +GNUnet's PEERSTORE subsystem offers persistent per-peer storage for +other GNUnet subsystems. GNUnet subsystems can use PEERSTORE to +persistently store and retrieve arbitrary data. Each data record stored +with PEERSTORE contains the following fields: + +- subsystem: Name of the subsystem responsible for the record. + +- peerid: Identity of the peer this record is related to. + +- key: a key string identifying the record. + +- value: binary record value. + +- expiry: record expiry date. + +.. _Functionality: + +Functionality +------------- + +Subsystems can store any type of value under a (subsystem, peerid, key) +combination. A \"replace\" flag set during store operations forces the +PEERSTORE to replace any old values stored under the same (subsystem, +peerid, key) combination with the new value. Additionally, an expiry +date is set after which the record is \*possibly\* deleted by PEERSTORE. + +Subsystems can iterate over all values stored under any of the following +combination of fields: + +- (subsystem) + +- (subsystem, peerid) + +- (subsystem, key) + +- (subsystem, peerid, key) + +Subsystems can also request to be notified about any new values stored +under a (subsystem, peerid, key) combination by sending a \"watch\" +request to PEERSTORE. + +.. _Architecture: + +Architecture +------------ + +PEERSTORE implements the following components: + +- PEERSTORE service: Handles store, iterate and watch operations. + +- PEERSTORE API: API to be used by other subsystems to communicate and + issue commands to the PEERSTORE service. + +- PEERSTORE plugins: Handles the persistent storage. At the moment, + only an \"sqlite\" plugin is implemented. + +:index:`libgnunetpeerstore <single: libgnunet; peerstore>` +---------------------------------------------------------- + +libgnunetpeerstore is the library containing the PEERSTORE API. +Subsystems wishing to communicate with the PEERSTORE service use this +API to open a connection to PEERSTORE. This is done by calling +``GNUNET_PEERSTORE_connect`` which returns a handle to the newly created +connection. This handle has to be used with any further calls to the +API. + +To store a new record, the function ``GNUNET_PEERSTORE_store`` is to be +used which requires the record fields and a continuation function that +will be called by the API after the STORE request is sent to the +PEERSTORE service. Note that calling the continuation function does not +mean that the record is successfully stored, only that the STORE request +has been successfully sent to the PEERSTORE service. +``GNUNET_PEERSTORE_store_cancel`` can be called to cancel the STORE +request only before the continuation function has been called. + +To iterate over stored records, the function +``GNUNET_PEERSTORE_iterate`` is to be used. *peerid* and *key* can be +set to NULL. An iterator callback function will be called with each +matching record found and a NULL record at the end to signal the end of +result set. ``GNUNET_PEERSTORE_iterate_cancel`` can be used to cancel +the ITERATE request before the iterator callback is called with a NULL +record. + +To be notified with new values stored under a (subsystem, peerid, key) +combination, the function ``GNUNET_PEERSTORE_watch`` is to be used. This +will register the watcher with the PEERSTORE service, any new records +matching the given combination will trigger the callback function passed +to ``GNUNET_PEERSTORE_watch``. This continues until +``GNUNET_PEERSTORE_watch_cancel`` is called or the connection to the +service is destroyed. + +After the connection is no longer needed, the function +``GNUNET_PEERSTORE_disconnect`` can be called to disconnect from the +PEERSTORE service. Any pending ITERATE or WATCH requests will be +destroyed. If the ``sync_first`` flag is set to ``GNUNET_YES``, the API +will delay the disconnection until all pending STORE requests are sent +to the PEERSTORE service, otherwise, the pending STORE requests will be +destroyed as well. + + diff --git a/man_developers/subsystems/regex/regex.rst b/man_developers/subsystems/regex/regex.rst @@ -0,0 +1,152 @@ + +.. index:: + double: subsystem; REGEX + +.. _REGEX-Subsystem: + +REGEX — Service discovery using regular expressions +=================================================== + +Using the REGEX subsystem, you can discover peers that offer a +particular service using regular expressions. The peers that offer a +service specify it using a regular expressions. Peers that want to +patronize a service search using a string. The REGEX subsystem will then +use the DHT to return a set of matching offerers to the patrons. + +For the technical details, we have Max's defense talk and Max's Master's +thesis. + +.. note:: An additional publication is under preparation and available + to team members (in Git). + +.. todo:: Missing links to Max's talk and Master's thesis + +.. _How-to-run-the-regex-profiler: + +How to run the regex profiler +----------------------------- + +The gnunet-regex-profiler can be used to profile the usage of mesh/regex +for a given set of regular expressions and strings. Mesh/regex allows +you to announce your peer ID under a certain regex and search for peers +matching a particular regex using a string. See +`szengel2012ms <https://bib.gnunet.org/full/date.html#2012_5f2>`__ for a +full introduction. + +First of all, the regex profiler uses GNUnet testbed, thus all the +implications for testbed also apply to the regex profiler (for example +you need password-less ssh login to the machines listed in your hosts +file). + +**Configuration** + +Moreover, an appropriate configuration file is needed. In the following +paragraph the important details are highlighted. + +Announcing of the regular expressions is done by the +gnunet-daemon-regexprofiler, therefore you have to make sure it is +started, by adding it to the START_ON_DEMAND set of ARM: + +:: + + [regexprofiler] + START_ON_DEMAND = YES + +Furthermore you have to specify the location of the binary: + +:: + + [regexprofiler] + # Location of the gnunet-daemon-regexprofiler binary. + BINARY = /home/szengel/gnunet/src/mesh/.libs/gnunet-daemon-regexprofiler + # Regex prefix that will be applied to all regular expressions and + # search string. + REGEX_PREFIX = "GNVPN-0001-PAD" + +When running the profiler with a large scale deployment, you probably +want to reduce the workload of each peer. Use the following options to +do this. + +:: + + [dht] + # Force network size estimation + FORCE_NSE = 1 + + [dhtcache] + DATABASE = heap + # Disable RC-file for Bloom filter? (for benchmarking with limited IO + # availability) + DISABLE_BF_RC = YES + # Disable Bloom filter entirely + DISABLE_BF = YES + + [nse] + # Minimize proof-of-work CPU consumption by NSE + WORKBITS = 1 + +**Options** + +To finally run the profiler some options and the input data need to be +specified on the command line. + +:: + + gnunet-regex-profiler -c config-file -d log-file -n num-links \ + -p path-compression-length -s search-delay -t matching-timeout \ + -a num-search-strings hosts-file policy-dir search-strings-file + +Where\... + +- \... ``config-file`` means the configuration file created earlier. + +- \... ``log-file`` is the file where to write statistics output. + +- \... ``num-links`` indicates the number of random links between + started peers. + +- \... ``path-compression-length`` is the maximum path compression + length in the DFA. + +- \... ``search-delay`` time to wait between peers finished linking and + starting to match strings. + +- \... ``matching-timeout`` timeout after which to cancel the + searching. + +- \... ``num-search-strings`` number of strings in the + search-strings-file. + +- \... the ``hosts-file`` should contain a list of hosts for the + testbed, one per line in the following format: + + - ``user@host_ip:port`` + +- \... the ``policy-dir`` is a folder containing text files containing + one or more regular expressions. A peer is started for each file in + that folder and the regular expressions in the corresponding file are + announced by this peer. + +- \... the ``search-strings-file`` is a text file containing search + strings, one in each line. + +You can create regular expressions and search strings for every AS in +the Internet using the attached scripts. You need one of the `CAIDA +routeviews +prefix2as <http://data.caida.org/datasets/routing/routeviews-prefix2as/>`__ +data files for this. Run + +:: + + create_regex.py <filename> <output path> + +to create the regular expressions and + +:: + + create_strings.py <input path> <outfile> + +to create a search strings file from the previously created regular +expressions. + + diff --git a/man_developers/subsystems/rest/rest.rst b/man_developers/subsystems/rest/rest.rst @@ -0,0 +1,53 @@ + +.. index:: + double: subsystem; REST + +.. _REST-Subsystem: + +REST — RESTful GNUnet Web APIs +============================== + +.. todo:: Define REST + +Using the REST subsystem, you can expose REST-based APIs or services. +The REST service is designed as a pluggable architecture. To create a +new REST endpoint, simply add a library in the form "plugin_rest_*". The +REST service will automatically load all REST plugins on startup. + +**Configuration** + +The REST service can be configured in various ways. The reference config +file can be found in ``src/rest/rest.conf``: + +:: + + [rest] + REST_PORT=7776 + REST_ALLOW_HEADERS=Authorization,Accept,Content-Type + REST_ALLOW_ORIGIN=* + REST_ALLOW_CREDENTIALS=true + +The port as well as CORS (cross-origin resource sharing) headers +that are supposed to be advertised by the rest service are configurable. + +.. _Namespace-considerations: + +Namespace considerations +------------------------ + +The ``gnunet-rest-service`` will load all plugins that are installed. As +such it is important that the endpoint namespaces do not clash. + +For example, plugin X might expose the endpoint "/xxx" while plugin Y +exposes endpoint "/xxx/yyy". This is a problem if plugin X is also +supposed to handle a call to "/xxx/yyy". Currently the REST service will +not complain or warn about such clashes, so please make sure that +endpoints are unambiguous. + +.. _Endpoint-documentation: + +Endpoint documentation +---------------------- + +This is WIP. Endpoints should be documented appropriately. Preferably +using annotations. diff --git a/man_developers/subsystems/revocation/revocation.rst b/man_developers/subsystems/revocation/revocation.rst @@ -0,0 +1,172 @@ + +.. index:: + double: subsystem; REVOCATION + +.. _REVOCATION-Subsystem: + +REVOCATION — Ego key revocation +=============================== + +The REVOCATION subsystem is responsible for key revocation of Egos. If a +user learns that their private key has been compromised or has lost it, +they can use the REVOCATION system to inform all of the other users that +their private key is no longer valid. The subsystem thus includes ways +to query for the validity of keys and to propagate revocation messages. + +.. _Dissemination: + +Dissemination +------------- + +When a revocation is performed, the revocation is first of all +disseminated by flooding the overlay network. The goal is to reach every +peer, so that when a peer needs to check if a key has been revoked, this +will be purely a local operation where the peer looks at its local +revocation list. Flooding the network is also the most robust form of +key revocation --- an adversary would have to control a separator of the +overlay graph to restrict the propagation of the revocation message. +Flooding is also very easy to implement --- peers that receive a +revocation message for a key that they have never seen before simply +pass the message to all of their neighbours. + +Flooding can only distribute the revocation message to peers that are +online. In order to notify peers that join the network later, the +revocation service performs efficient set reconciliation over the sets +of known revocation messages whenever two peers (that both support +REVOCATION dissemination) connect. The SET service is used to perform +this operation efficiently. + +.. _Revocation-Message-Design-Requirements: + +Revocation Message Design Requirements +-------------------------------------- + +However, flooding is also quite costly, creating O(\|E\|) messages on a +network with \|E\| edges. Thus, revocation messages are required to +contain a proof-of-work, the result of an expensive computation (which, +however, is cheap to verify). Only peers that have expended the CPU time +necessary to provide this proof will be able to flood the network with +the revocation message. This ensures that an attacker cannot simply +flood the network with millions of revocation messages. The +proof-of-work required by GNUnet is set to take days on a typical PC to +compute; if the ability to quickly revoke a key is needed, users have +the option to pre-compute revocation messages to store off-line and use +instantly after their key has expired. + +Revocation messages must also be signed by the private key that is being +revoked. Thus, they can only be created while the private key is in the +possession of the respective user. This is another reason to create a +revocation message ahead of time and store it in a secure location. + +:index:`libgnunetrevocation <single: libgnunet; revocation>` +------------------------------------------------------------ + +The REVOCATION API consists of two parts, to query and to issue +revocations. + +.. _Querying-for-revoked-keys: + +Querying for revoked keys +^^^^^^^^^^^^^^^^^^^^^^^^^ + +``GNUNET_REVOCATION_query`` is used to check if a given ECDSA public key +has been revoked. The given callback will be invoked with the result of +the check. The query can be canceled using +``GNUNET_REVOCATION_query_cancel`` on the return value. + +.. _Preparing-revocations: + +Preparing revocations +^^^^^^^^^^^^^^^^^^^^^ + +It is often desirable to create a revocation record ahead-of-time and +store it in an off-line location to be used later in an emergency. This +is particularly true for GNUnet revocations, where performing the +revocation operation itself is computationally expensive and thus is +likely to take some time. Thus, if users want the ability to perform +revocations quickly in an emergency, they must pre-compute the +revocation message. The revocation API enables this with two functions +that are used to compute the revocation message, but not trigger the +actual revocation operation. + +``GNUNET_REVOCATION_check_pow`` should be used to calculate the +proof-of-work required in the revocation message. This function takes +the public key, the required number of bits for the proof of work (which +in GNUnet is a network-wide constant) and finally a proof-of-work number +as arguments. The function then checks if the given proof-of-work number +is a valid proof of work for the given public key. Clients preparing a +revocation are expected to call this function repeatedly (typically with +a monotonically increasing sequence of numbers of the proof-of-work +number) until a given number satisfies the check. That number should +then be saved for later use in the revocation operation. + +``GNUNET_REVOCATION_sign_revocation`` is used to generate the signature +that is required in a revocation message. It takes the private key that +(possibly in the future) is to be revoked and returns the signature. The +signature can again be saved to disk for later use, which will then +allow performing a revocation even without access to the private key. + +.. _Issuing-revocations: + +Issuing revocations +^^^^^^^^^^^^^^^^^^^ + +Given a ECDSA public key, the signature from ``GNUNET_REVOCATION_sign`` +and the proof-of-work, ``GNUNET_REVOCATION_revoke`` can be used to +perform the actual revocation. The given callback is called upon +completion of the operation. ``GNUNET_REVOCATION_revoke_cancel`` can be +used to stop the library from calling the continuation; however, in that +case it is undefined whether or not the revocation operation will be +executed. + +.. _The-REVOCATION-Client_002dService-Protocol: + +The REVOCATION Client-Service Protocol +-------------------------------------- + +The REVOCATION protocol consists of four simple messages. + +A ``QueryMessage`` containing a public ECDSA key is used to check if a +particular key has been revoked. The service responds with a +``QueryResponseMessage`` which simply contains a bit that says if the +given public key is still valid, or if it has been revoked. + +The second possible interaction is for a client to revoke a key by +passing a ``RevokeMessage`` to the service. The ``RevokeMessage`` +contains the ECDSA public key to be revoked, a signature by the +corresponding private key and the proof-of-work. The service responds +with a ``RevocationResponseMessage`` which can be used to indicate that +the ``RevokeMessage`` was invalid (e.g. the proof of work is incorrect), +or otherwise to indicate that the revocation has been processed +successfully. + +.. _The-REVOCATION-Peer_002dto_002dPeer-Protocol: + +The REVOCATION Peer-to-Peer Protocol +------------------------------------ + +Revocation uses two disjoint ways to spread revocation information among +peers. First of all, P2P gossip exchanged via CORE-level neighbours is +used to quickly spread revocations to all connected peers. Second, +whenever two peers (that both support revocations) connect, the SET +service is used to compute the union of the respective revocation sets. + +In both cases, the exchanged messages are ``RevokeMessage``\ s which +contain the public key that is being revoked, a matching ECDSA +signature, and a proof-of-work. Whenever a peer learns about a new +revocation this way, it first validates the signature and the +proof-of-work, then stores it to disk (typically to a file +$GNUNET_DATA_HOME/revocation.dat) and finally spreads the information to +all directly connected neighbours. + +For computing the union using the SET service, the peer with the smaller +hashed peer identity will connect (as a \"client\" in the two-party set +protocol) to the other peer after one second (to reduce traffic spikes +on connect) and initiate the computation of the set union. All +revocation services use a common hash to identify the SET operation over +revocation sets. + +The current implementation accepts revocation set union operations from +all peers at any time; however, well-behaved peers should only initiate +this operation once after establishing a connection to a peer with a +larger hashed peer identity. diff --git a/man_developers/subsystems/rps/rps.rst b/man_developers/subsystems/rps/rps.rst @@ -0,0 +1,76 @@ + +.. index:: + double: subsystems; Random peer sampling + see: RPS; Random peer sampling + +.. _RPS-Subsystem: + +RPS — Random peer sampling +========================== + +In literature, Random Peer Sampling (RPS) refers to the problem of +reliably [1]_ drawing random samples from an unstructured p2p network. + +Doing so in a reliable manner is not only hard because of inherent +problems but also because of possible malicious peers that could try to +bias the selection. + +It is useful for all kind of gossip protocols that require the selection +of random peers in the whole network like gathering statistics, +spreading and aggregating information in the network, load balancing and +overlay topology management. + +The approach chosen in the RPS service implementation in GNUnet follows +the `Brahms <https://bib.gnunet.org/full/date.html\#2009_5f0>`__ design. + +The current state is \"work in progress\". There are a lot of things +that need to be done, primarily finishing the experimental evaluation +and a re-design of the API. + +The abstract idea is to subscribe to connect to/start the RPS service +and request random peers that will be returned when they represent a +random selection from the whole network with high probability. + +An additional feature to the original Brahms-design is the selection of +sub-groups: The GNUnet implementation of RPS enables clients to ask for +random peers from a group that is defined by a common shared secret. +(The secret could of course also be public, depending on the use-case.) + +Another addition to the original protocol was made: The sampler +mechanism that was introduced in Brahms was slightly adapted and used to +actually sample the peers and returned to the client. This is necessary +as the original design only keeps peers connected to random other peers +in the network. In order to return random peers to client requests +independently random, they cannot be drawn from the connected peers. The +adapted sampler makes sure that each request for random peers is +independent from the others. + +.. _Brahms: + +Brahms +------ + +The high-level concept of Brahms is two-fold: Combining push-pull gossip +with locally fixing a assumed bias using cryptographic min-wise +permutations. The central data structure is the view - a peer's current +local sample. This view is used to select peers to push to and pull +from. This simple mechanism can be biased easily. For this reason Brahms +'fixes' the bias by using the so-called sampler. A data structure that +takes a list of elements as input and outputs a random one of them +independently of the frequency in the input set. Both an element that +was put into the sampler a single time and an element that was put into +it a million times have the same probability of being the output. This +is achieved with exploiting min-wise independent permutations. In the +RPS service we use HMACs: On the initialisation of a sampler element, a +key is chosen at random. On each input the HMAC with the random key is +computed. The sampler element keeps the element with the minimal HMAC. + +In order to fix the bias in the view, a fraction of the elements in the +view are sampled through the sampler from the random stream of peer IDs. + +According to the theoretical analysis of Bortnikov et al. this suffices +to keep the network connected and having random peers in the view. + +.. [1] + \"Reliable\" in this context means having no bias, neither spatial, + nor temporal, nor through malicious activity. diff --git a/man_developers/subsystems/set/set.rst b/man_developers/subsystems/set/set.rst @@ -0,0 +1,336 @@ +.. index:: + double: subsystem; SET + +.. _SET-Subsystem: + +SET — Peer to peer set operations (Deprecated) +============================================== + +.. note:: + + The SET subsystem is in process of being replaced by the SETU and SETI + subsystems, which provide basically the same functionality, just using + two different subsystems. SETI and SETU should be used for new code. + +The SET service implements efficient set operations between two peers +over a CADET tunnel. Currently, set union and set intersection are the +only supported operations. Elements of a set consist of an *element +type* and arbitrary binary *data*. The size of an element's data is +limited to around 62 KB. + +.. _Local-Sets: + +Local Sets +---------- + +Sets created by a local client can be modified and reused for multiple +operations. As each set operation requires potentially expensive special +auxiliary data to be computed for each element of a set, a set can only +participate in one type of set operation (either union or intersection). +The type of a set is determined upon its creation. If a the elements of +a set are needed for an operation of a different type, all of the set's +element must be copied to a new set of appropriate type. + +.. _Set-Modifications: + +Set Modifications +----------------- + +Even when set operations are active, one can add to and remove elements +from a set. However, these changes will only be visible to operations +that have been created after the changes have taken place. That is, +every set operation only sees a snapshot of the set from the time the +operation was started. This mechanism is *not* implemented by copying +the whole set, but by attaching *generation information* to each element +and operation. + +.. _Set-Operations: + +Set Operations +-------------- + +Set operations can be started in two ways: Either by accepting an +operation request from a remote peer, or by requesting a set operation +from a remote peer. Set operations are uniquely identified by the +involved *peers*, an *application id* and the *operation type*. + +The client is notified of incoming set operations by *set listeners*. A +set listener listens for incoming operations of a specific operation +type and application id. Once notified of an incoming set request, the +client can accept the set request (providing a local set for the +operation) or reject it. + +.. _Result-Elements: + +Result Elements +--------------- + +The SET service has three *result modes* that determine how an +operation's result set is delivered to the client: + +- **Full Result Set.** All elements of set resulting from the set + operation are returned to the client. + +- **Added Elements.** Only elements that result from the operation and + are not already in the local peer's set are returned. Note that for + some operations (like set intersection) this result mode will never + return any elements. This can be useful if only the remove peer is + actually interested in the result of the set operation. + +- **Removed Elements.** Only elements that are in the local peer's + initial set but not in the operation's result set are returned. Note + that for some operations (like set union) this result mode will never + return any elements. This can be useful if only the remove peer is + actually interested in the result of the set operation. + + +:index:`libgnunetset <single: libgnunet; set>` +---------------------------------------------- + +.. _Sets: + +Sets +^^^^ + +New sets are created with ``GNUNET_SET_create``. Both the local peer's +configuration (as each set has its own client connection) and the +operation type must be specified. The set exists until either the client +calls ``GNUNET_SET_destroy`` or the client's connection to the service +is disrupted. In the latter case, the client is notified by the return +value of functions dealing with sets. This return value must always be +checked. + +Elements are added and removed with ``GNUNET_SET_add_element`` and +``GNUNET_SET_remove_element``. + +.. _Listeners: + +Listeners +^^^^^^^^^ + +Listeners are created with ``GNUNET_SET_listen``. Each time time a +remote peer suggests a set operation with an application id and +operation type matching a listener, the listener's callback is invoked. +The client then must synchronously call either ``GNUNET_SET_accept`` or +``GNUNET_SET_reject``. Note that the operation will not be started until +the client calls ``GNUNET_SET_commit`` (see Section \"Supplying a +Set\"). + +.. _Operations: + +Operations +^^^^^^^^^^ + +Operations to be initiated by the local peer are created with +``GNUNET_SET_prepare``. Note that the operation will not be started +until the client calls ``GNUNET_SET_commit`` (see Section \"Supplying a +Set\"). + +.. _Supplying-a-Set: + +Supplying a Set +^^^^^^^^^^^^^^^ + +To create symmetry between the two ways of starting a set operation +(accepting and initiating it), the operation handles returned by +``GNUNET_SET_accept`` and ``GNUNET_SET_prepare`` do not yet have a set +to operate on, thus they can not do any work yet. + +The client must call ``GNUNET_SET_commit`` to specify a set to use for +an operation. ``GNUNET_SET_commit`` may only be called once per set +operation. + +.. _The-Result-Callback: + +The Result Callback +^^^^^^^^^^^^^^^^^^^ + +Clients must specify both a result mode and a result callback with +``GNUNET_SET_accept`` and ``GNUNET_SET_prepare``. The result callback +with a status indicating either that an element was received, or the +operation failed or succeeded. The interpretation of the received +element depends on the result mode. The callback needs to know which +result mode it is used in, as the arguments do not indicate if an +element is part of the full result set, or if it is in the difference +between the original set and the final set. + +.. _The-SET-Client_002dService-Protocol: + +The SET Client-Service Protocol +------------------------------- + +.. _Creating-Sets: + +Creating Sets +^^^^^^^^^^^^^ + +For each set of a client, there exists a client connection to the +service. Sets are created by sending the ``GNUNET_SERVICE_SET_CREATE`` +message over a new client connection. Multiple operations for one set +are multiplexed over one client connection, using a request id supplied +by the client. + +.. _Listeners2: + +Listeners +^^^^^^^^^ + +Each listener also requires a separate client connection. By sending the +``GNUNET_SERVICE_SET_LISTEN`` message, the client notifies the service +of the application id and operation type it is interested in. A client +rejects an incoming request by sending ``GNUNET_SERVICE_SET_REJECT`` on +the listener's client connection. In contrast, when accepting an +incoming request, a ``GNUNET_SERVICE_SET_ACCEPT`` message must be sent +over the set that is supplied for the set operation. + +.. _Initiating-Operations: + +Initiating Operations +^^^^^^^^^^^^^^^^^^^^^ + +Operations with remote peers are initiated by sending a +``GNUNET_SERVICE_SET_EVALUATE`` message to the service. The client +connection that this message is sent by determines the set to use. + +.. _Modifying-Sets: + +Modifying Sets +^^^^^^^^^^^^^^ + +Sets are modified with the ``GNUNET_SERVICE_SET_ADD`` and +``GNUNET_SERVICE_SET_REMOVE`` messages. + +.. _Results-and-Operation-Status: + +Results and Operation Status +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The service notifies the client of result elements and success/failure +of a set operation with the ``GNUNET_SERVICE_SET_RESULT`` message. + +.. _Iterating-Sets: + +Iterating Sets +^^^^^^^^^^^^^^ + +All elements of a set can be requested by sending +``GNUNET_SERVICE_SET_ITER_REQUEST``. The server responds with +``GNUNET_SERVICE_SET_ITER_ELEMENT`` and eventually terminates the +iteration with ``GNUNET_SERVICE_SET_ITER_DONE``. After each received +element, the client must send ``GNUNET_SERVICE_SET_ITER_ACK``. Note that +only one set iteration may be active for a set at any given time. + +.. _The-SET-Intersection-Peer_002dto_002dPeer-Protocol: + +The SET Intersection Peer-to-Peer Protocol +------------------------------------------ + +The intersection protocol operates over CADET and starts with a +GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer +initiating the operation to the peer listening for inbound requests. It +includes the number of elements of the initiating peer, which is used to +decide which side will send a Bloom filter first. + +The listening peer checks if the operation type and application +identifier are acceptable for its current state. If not, it responds +with a GNUNET_MESSAGE_TYPE_SET_RESULT and a status of +GNUNET_SET_STATUS_FAILURE (and terminates the CADET channel). + +If the application accepts the request, the listener sends back a +``GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO`` if it has more +elements in the set than the client. Otherwise, it immediately starts +with the Bloom filter exchange. If the initiator receives a +``GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO`` response, it +beings the Bloom filter exchange, unless the set size is indicated to be +zero, in which case the intersection is considered finished after just +the initial handshake. + +.. _The-Bloom-filter-exchange: + +The Bloom filter exchange +^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this phase, each peer transmits a Bloom filter over the remaining +keys of the local set to the other peer using a +``GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF`` message. This message +additionally includes the number of elements left in the sender's set, +as well as the XOR over all of the keys in that set. + +The number of bits 'k' set per element in the Bloom filter is calculated +based on the relative size of the two sets. Furthermore, the size of the +Bloom filter is calculated based on 'k' and the number of elements in +the set to maximize the amount of data filtered per byte transmitted on +the wire (while avoiding an excessively high number of iterations). + +The receiver of the message removes all elements from its local set that +do not pass the Bloom filter test. It then checks if the set size of the +sender and the XOR over the keys match what is left of its own set. If +they do, it sends a ``GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE`` +back to indicate that the latest set is the final result. Otherwise, the +receiver starts another Bloom filter exchange, except this time as the +sender. + +.. _Salt: + +Salt +^^^^ + +Bloomfilter operations are probabilistic: With some non-zero probability +the test may incorrectly say an element is in the set, even though it is +not. + +To mitigate this problem, the intersection protocol iterates exchanging +Bloom filters using a different random 32-bit salt in each iteration +(the salt is also included in the message). With different salts, set +operations may fail for different elements. Merging the results from the +executions, the probability of failure drops to zero. + +The iterations terminate once both peers have established that they have +sets of the same size, and where the XOR over all keys computes the same +512-bit value (leaving a failure probability of 2\ :superscript:`-511`\ ). + +.. _The-SET-Union-Peer_002dto_002dPeer-Protocol: + +The SET Union Peer-to-Peer Protocol +----------------------------------- + +The SET union protocol is based on Eppstein's efficient set +reconciliation without prior context. You should read this paper first +if you want to understand the protocol. + +.. todo:: Link to Eppstein's paper! + +The union protocol operates over CADET and starts with a +GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer +initiating the operation to the peer listening for inbound requests. It +includes the number of elements of the initiating peer, which is +currently not used. + +The listening peer checks if the operation type and application +identifier are acceptable for its current state. If not, it responds +with a ``GNUNET_MESSAGE_TYPE_SET_RESULT`` and a status of +``GNUNET_SET_STATUS_FAILURE`` (and terminates the CADET channel). + +If the application accepts the request, it sends back a strata estimator +using a message of type GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE. The +initiator evaluates the strata estimator and initiates the exchange of +invertible Bloom filters, sending a +GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF. + +During the IBF exchange, if the receiver cannot invert the Bloom filter +or detects a cycle, it sends a larger IBF in response (up to a defined +maximum limit; if that limit is reached, the operation fails). Elements +decoded while processing the IBF are transmitted to the other peer using +GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, or requested from the other peer +using GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS messages, depending +on the sign observed during decoding of the IBF. Peers respond to a +GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS message with the respective +element in a GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS message. If the IBF +fully decodes, the peer responds with a +GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE message instead of another +GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF. + +All Bloom filter operations use a salt to mingle keys before hashing +them into buckets, such that future iterations have a fresh chance of +succeeding if they failed due to collisions before. + diff --git a/man_developers/subsystems/seti/seti.rst b/man_developers/subsystems/seti/seti.rst @@ -0,0 +1,257 @@ +.. index:: + double: subsystem; SETI + +.. _SETI-Subsystem: + +SETI — Peer to peer set intersections +===================================== + +The SETI service implements efficient set intersection between two peers +over a CADET tunnel. Elements of a set consist of an *element type* and +arbitrary binary *data*. The size of an element's data is limited to +around 62 KB. + +.. _Intersection-Sets: + +Intersection Sets +----------------- + +Sets created by a local client can be modified (by adding additional +elements) and reused for multiple operations. If elements are to be +removed, a fresh set must be created by the client. + +.. _Set-Intersection-Modifications: + +Set Intersection Modifications +------------------------------ + +Even when set operations are active, one can add elements to a set. +However, these changes will only be visible to operations that have been +created after the changes have taken place. That is, every set operation +only sees a snapshot of the set from the time the operation was started. +This mechanism is *not* implemented by copying the whole set, but by +attaching *generation information* to each element and operation. + +.. _Set-Intersection-Operations: + +Set Intersection Operations +--------------------------- + +Set operations can be started in two ways: Either by accepting an +operation request from a remote peer, or by requesting a set operation +from a remote peer. Set operations are uniquely identified by the +involved *peers*, an *application id* and the *operation type*. + +The client is notified of incoming set operations by *set listeners*. A +set listener listens for incoming operations of a specific operation +type and application id. Once notified of an incoming set request, the +client can accept the set request (providing a local set for the +operation) or reject it. + +.. _Intersection-Result-Elements: + +Intersection Result Elements +---------------------------- + +The SET service has two *result modes* that determine how an operation's +result set is delivered to the client: + +- **Return intersection.** All elements of set resulting from the set + intersection are returned to the client. + +- **Removed Elements.** Only elements that are in the local peer's + initial set but not in the intersection are returned. + + +:index:`libgnunetseti <single: libgnunet; seti>` +------------------------------------------------ + +.. _Intersection-Set-API: + +Intersection Set API +^^^^^^^^^^^^^^^^^^^^ + +New sets are created with ``GNUNET_SETI_create``. Only the local peer's +configuration (as each set has its own client connection) must be +provided. The set exists until either the client calls +``GNUNET_SET_destroy`` or the client's connection to the service is +disrupted. In the latter case, the client is notified by the return +value of functions dealing with sets. This return value must always be +checked. + +Elements are added with ``GNUNET_SET_add_element``. + +.. _Intersection-Listeners: + +Intersection Listeners +^^^^^^^^^^^^^^^^^^^^^^ + +Listeners are created with ``GNUNET_SET_listen``. Each time time a +remote peer suggests a set operation with an application id and +operation type matching a listener, the listener's callback is invoked. +The client then must synchronously call either ``GNUNET_SET_accept`` or +``GNUNET_SET_reject``. Note that the operation will not be started until +the client calls ``GNUNET_SET_commit`` (see Section \"Supplying a +Set\"). + +.. _Intersection-Operations: + +Intersection Operations +^^^^^^^^^^^^^^^^^^^^^^^ + +Operations to be initiated by the local peer are created with +``GNUNET_SET_prepare``. Note that the operation will not be started +until the client calls ``GNUNET_SET_commit`` (see Section \"Supplying a +Set\"). + +.. _Supplying-a-Set-for-Intersection: + +Supplying a Set for Intersection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To create symmetry between the two ways of starting a set operation +(accepting and initiating it), the operation handles returned by +``GNUNET_SET_accept`` and ``GNUNET_SET_prepare`` do not yet have a set +to operate on, thus they can not do any work yet. + +The client must call ``GNUNET_SET_commit`` to specify a set to use for +an operation. ``GNUNET_SET_commit`` may only be called once per set +operation. + +.. _The-Intersection-Result-Callback: + +The Intersection Result Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Clients must specify both a result mode and a result callback with +``GNUNET_SET_accept`` and ``GNUNET_SET_prepare``. The result callback +with a status indicating either that an element was received, or the +operation failed or succeeded. The interpretation of the received +element depends on the result mode. The callback needs to know which +result mode it is used in, as the arguments do not indicate if an +element is part of the full result set, or if it is in the difference +between the original set and the final set. + +.. _The-SETI-Client_002dService-Protocol: + +The SETI Client-Service Protocol +-------------------------------- + +.. _Creating-Intersection-Sets: + +Creating Intersection Sets +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For each set of a client, there exists a client connection to the +service. Sets are created by sending the ``GNUNET_SERVICE_SETI_CREATE`` +message over a new client connection. Multiple operations for one set +are multiplexed over one client connection, using a request id supplied +by the client. + +.. _Listeners-for-Intersection: + +Listeners for Intersection +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each listener also requires a separate client connection. By sending the +``GNUNET_SERVICE_SETI_LISTEN`` message, the client notifies the service +of the application id and operation type it is interested in. A client +rejects an incoming request by sending ``GNUNET_SERVICE_SETI_REJECT`` on +the listener's client connection. In contrast, when accepting an +incoming request, a ``GNUNET_SERVICE_SETI_ACCEPT`` message must be sent +over the set that is supplied for the set operation. + +.. _Initiating-Intersection-Operations: + +Initiating Intersection Operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Operations with remote peers are initiated by sending a +``GNUNET_SERVICE_SETI_EVALUATE`` message to the service. The client +connection that this message is sent by determines the set to use. + +.. _Modifying-Intersection-Sets: + +Modifying Intersection Sets +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sets are modified with the ``GNUNET_SERVICE_SETI_ADD`` message. + +.. _Intersection-Results-and-Operation-Status: + +Intersection Results and Operation Status +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The service notifies the client of result elements and success/failure +of a set operation with the ``GNUNET_SERVICE_SETI_RESULT`` message. + +.. _The-SETI-Intersection-Peer_002dto_002dPeer-Protocol: + +The SETI Intersection Peer-to-Peer Protocol +------------------------------------------- + +The intersection protocol operates over CADET and starts with a +GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST being sent by the peer +initiating the operation to the peer listening for inbound requests. It +includes the number of elements of the initiating peer, which is used to +decide which side will send a Bloom filter first. + +The listening peer checks if the operation type and application +identifier are acceptable for its current state. If not, it responds +with a GNUNET_MESSAGE_TYPE_SETI_RESULT and a status of +GNUNET_SETI_STATUS_FAILURE (and terminates the CADET channel). + +If the application accepts the request, the listener sends back a +``GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO`` if it has more elements in +the set than the client. Otherwise, it immediately starts with the Bloom +filter exchange. If the initiator receives a +``GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO`` response, it beings the +Bloom filter exchange, unless the set size is indicated to be zero, in +which case the intersection is considered finished after just the +initial handshake. + +.. _The-Bloom-filter-exchange-in-SETI: + +The Bloom filter exchange in SETI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this phase, each peer transmits a Bloom filter over the remaining +keys of the local set to the other peer using a +``GNUNET_MESSAGE_TYPE_SETI_P2P_BF`` message. This message additionally +includes the number of elements left in the sender's set, as well as the +XOR over all of the keys in that set. + +The number of bits 'k' set per element in the Bloom filter is calculated +based on the relative size of the two sets. Furthermore, the size of the +Bloom filter is calculated based on 'k' and the number of elements in +the set to maximize the amount of data filtered per byte transmitted on +the wire (while avoiding an excessively high number of iterations). + +The receiver of the message removes all elements from its local set that +do not pass the Bloom filter test. It then checks if the set size of the +sender and the XOR over the keys match what is left of its own set. If +they do, it sends a ``GNUNET_MESSAGE_TYPE_SETI_P2P_DONE`` back to +indicate that the latest set is the final result. Otherwise, the +receiver starts another Bloom filter exchange, except this time as the +sender. + +.. _Intersection-Salt: + +Intersection Salt +^^^^^^^^^^^^^^^^^ + +Bloom filter operations are probabilistic: With some non-zero +probability the test may incorrectly say an element is in the set, even +though it is not. + +To mitigate this problem, the intersection protocol iterates exchanging +Bloom filters using a different random 32-bit salt in each iteration +(the salt is also included in the message). With different salts, set +operations may fail for different elements. Merging the results from the +executions, the probability of failure drops to zero. + +The iterations terminate once both peers have established that they have +sets of the same size, and where the XOR over all keys computes the same +512-bit value (leaving a failure probability of 2-511). + + diff --git a/man_developers/subsystems/setops.rst b/man_developers/subsystems/setops.rst @@ -0,0 +1,11 @@ + +Peer-to-Peer Set Operations +=========================== + +Many applications + +.. toctree:: + set/set.rst + seti/seti.rst + setu/setu.rst + diff --git a/man_developers/subsystems/setu/setu.rst b/man_developers/subsystems/setu/setu.rst @@ -0,0 +1,231 @@ + +.. index:: + double: SETU; subsystem + +.. _SETU-Subsystem: + +SETU — Peer to peer set unions +============================== + +The SETU service implements efficient set union operations between two +peers over a CADET tunnel. Elements of a set consist of an *element +type* and arbitrary binary *data*. The size of an element's data is +limited to around 62 KB. + +.. _Union-Sets: + +Union Sets +---------- + +Sets created by a local client can be modified (by adding additional +elements) and reused for multiple operations. If elements are to be +removed, a fresh set must be created by the client. + +.. _Set-Union-Modifications: + +Set Union Modifications +----------------------- + +Even when set operations are active, one can add elements to a set. +However, these changes will only be visible to operations that have been +created after the changes have taken place. That is, every set operation +only sees a snapshot of the set from the time the operation was started. +This mechanism is *not* implemented by copying the whole set, but by +attaching *generation information* to each element and operation. + +.. _Set-Union-Operations: + +Set Union Operations +-------------------- + +Set operations can be started in two ways: Either by accepting an +operation request from a remote peer, or by requesting a set operation +from a remote peer. Set operations are uniquely identified by the +involved *peers*, an *application id* and the *operation type*. + +The client is notified of incoming set operations by *set listeners*. A +set listener listens for incoming operations of a specific operation +type and application id. Once notified of an incoming set request, the +client can accept the set request (providing a local set for the +operation) or reject it. + +.. _Union-Result-Elements: + +Union Result Elements +--------------------- + +The SET service has three *result modes* that determine how an +operation's result set is delivered to the client: + +- **Locally added Elements.** Elements that are in the union but not + already in the local peer's set are returned. + +- **Remote added Elements.** Additionally, notify the client if the + remote peer lacked some elements and thus also return to the local + client those elements that we are sending to the remote peer to be + added to its union. Obtaining these elements requires setting the + ``GNUNET_SETU_OPTION_SYMMETRIC`` option. + + +:index:`libgnunetsetu <single: libgnunet; setu>` +------------------------------------------------ + +.. _Union-Set-API: + +Union Set API +^^^^^^^^^^^^^ + +New sets are created with ``GNUNET_SETU_create``. Only the local peer's +configuration (as each set has its own client connection) must be +provided. The set exists until either the client calls +``GNUNET_SETU_destroy`` or the client's connection to the service is +disrupted. In the latter case, the client is notified by the return +value of functions dealing with sets. This return value must always be +checked. + +Elements are added with ``GNUNET_SETU_add_element``. + +.. _Union-Listeners: + +Union Listeners +^^^^^^^^^^^^^^^ + +Listeners are created with ``GNUNET_SETU_listen``. Each time time a +remote peer suggests a set operation with an application id and +operation type matching a listener, the listener's callback is invoked. +The client then must synchronously call either ``GNUNET_SETU_accept`` or +``GNUNET_SETU_reject``. Note that the operation will not be started +until the client calls ``GNUNET_SETU_commit`` (see Section \"Supplying a +Set\"). + +.. _Union-Operations: + +Union Operations +^^^^^^^^^^^^^^^^ + +Operations to be initiated by the local peer are created with +``GNUNET_SETU_prepare``. Note that the operation will not be started +until the client calls ``GNUNET_SETU_commit`` (see Section \"Supplying a +Set\"). + +.. _Supplying-a-Set-for-Union: + +Supplying a Set for Union +^^^^^^^^^^^^^^^^^^^^^^^^^ + +To create symmetry between the two ways of starting a set operation +(accepting and initiating it), the operation handles returned by +``GNUNET_SETU_accept`` and ``GNUNET_SETU_prepare`` do not yet have a set +to operate on, thus they can not do any work yet. + +The client must call ``GNUNET_SETU_commit`` to specify a set to use for +an operation. ``GNUNET_SETU_commit`` may only be called once per set +operation. + +.. _The-Union-Result-Callback: + +The Union Result Callback +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Clients must specify both a result mode and a result callback with +``GNUNET_SETU_accept`` and ``GNUNET_SETU_prepare``. The result callback +with a status indicating either that an element was received, +transmitted to the other peer (if this information was requested), or if +the operation failed or ultimately succeeded. + +.. _The-SETU-Client_002dService-Protocol: + +The SETU Client-Service Protocol +-------------------------------- + +.. _Creating-Union-Sets: + +Creating Union Sets +^^^^^^^^^^^^^^^^^^^ + +For each set of a client, there exists a client connection to the +service. Sets are created by sending the ``GNUNET_SERVICE_SETU_CREATE`` +message over a new client connection. Multiple operations for one set +are multiplexed over one client connection, using a request id supplied +by the client. + +.. _Listeners-for-Union: + +Listeners for Union +^^^^^^^^^^^^^^^^^^^ + +Each listener also requires a separate client connection. By sending the +``GNUNET_SERVICE_SETU_LISTEN`` message, the client notifies the service +of the application id and operation type it is interested in. A client +rejects an incoming request by sending ``GNUNET_SERVICE_SETU_REJECT`` on +the listener's client connection. In contrast, when accepting an +incoming request, a ``GNUNET_SERVICE_SETU_ACCEPT`` message must be sent +over the set that is supplied for the set operation. + +.. _Initiating-Union-Operations: + +Initiating Union Operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Operations with remote peers are initiated by sending a +``GNUNET_SERVICE_SETU_EVALUATE`` message to the service. The client +connection that this message is sent by determines the set to use. + +.. _Modifying-Union-Sets: + +Modifying Union Sets +^^^^^^^^^^^^^^^^^^^^ + +Sets are modified with the ``GNUNET_SERVICE_SETU_ADD`` message. + +.. _Union-Results-and-Operation-Status: + +Union Results and Operation Status +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The service notifies the client of result elements and success/failure +of a set operation with the ``GNUNET_SERVICE_SETU_RESULT`` message. + +.. _The-SETU-Union-Peer_002dto_002dPeer-Protocol: + +The SETU Union Peer-to-Peer Protocol +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The SET union protocol is based on Eppstein's efficient set +reconciliation without prior context. You should read this paper first +if you want to understand the protocol. + +.. todo:: Link to Eppstein's paper! + +The union protocol operates over CADET and starts with a +GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST being sent by the peer +initiating the operation to the peer listening for inbound requests. It +includes the number of elements of the initiating peer, which is +currently not used. + +The listening peer checks if the operation type and application +identifier are acceptable for its current state. If not, it responds +with a ``GNUNET_MESSAGE_TYPE_SETU_RESULT`` and a status of +``GNUNET_SETU_STATUS_FAILURE`` (and terminates the CADET channel). + +If the application accepts the request, it sends back a strata estimator +using a message of type GNUNET_MESSAGE_TYPE_SETU_P2P_SE. The initiator +evaluates the strata estimator and initiates the exchange of invertible +Bloom filters, sending a GNUNET_MESSAGE_TYPE_SETU_P2P_IBF. + +During the IBF exchange, if the receiver cannot invert the Bloom filter +or detects a cycle, it sends a larger IBF in response (up to a defined +maximum limit; if that limit is reached, the operation fails). Elements +decoded while processing the IBF are transmitted to the other peer using +GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS, or requested from the other peer +using GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENT_REQUESTS messages, depending +on the sign observed during decoding of the IBF. Peers respond to a +GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENT_REQUESTS message with the +respective element in a GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS message. +If the IBF fully decodes, the peer responds with a +GNUNET_MESSAGE_TYPE_SETU_P2P_DONE message instead of another +GNUNET_MESSAGE_TYPE_SETU_P2P_IBF. + +All Bloom filter operations use a salt to mingle keys before hashing +them into buckets, such that future iterations have a fresh chance of +succeeding if they failed due to collisions before. diff --git a/man_developers/subsystems/stability.rst b/man_developers/subsystems/stability.rst @@ -0,0 +1,136 @@ +.. _Subsystem-stability: + +Subsystem stability +------------------- + +This page documents the current stability of the various GNUnet +subsystems. Stability here describes the expected degree of +compatibility with future versions of GNUnet. + +For each subsystem we distinguish between compatibility on the P2P +network level (communication protocol between peers), the IPC level +(communication between the service and the service library) and the +API level (stability of the API). + +P2P compatibility is relevant in terms of which applications are likely +going to be able to communicate with future versions of the network. +IPC communication is relevant for the implementation of language bindings +that re-implement the IPC messages. Finally, API compatibility is relevant +to developers that hope to be able to avoid changes to applications built +on top of the APIs of the framework. + +The following table summarizes our current view of the stability of the +respective protocols or APIs: + +.. todo:: Make table automatically generated individual pages? + ++-----------------+-----------------+-----------------+-----------------+ +| Subsystem | P2P | IPC | C API | ++=================+=================+=================+=================+ +| util | n/a | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| arm | n/a | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| ats | n/a | unstable | testing | ++-----------------+-----------------+-----------------+-----------------+ +| block | n/a | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| cadet | testing | testing | testing | ++-----------------+-----------------+-----------------+-----------------+ +| consensus | experimental | experimental | experimental | ++-----------------+-----------------+-----------------+-----------------+ +| core | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| datacache | n/a | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| datastore | n/a | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| dht | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| dns | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| dv | testing | testing | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| exit | testing | n/a | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| fragmentation | stable | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| fs | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| gns | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| hello | n/a | n/a | testing | ++-----------------+-----------------+-----------------+-----------------+ +| hostlist | stable | stable | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| identity | stable | stable | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| multicast | experimental | experimental | experimental | ++-----------------+-----------------+-----------------+-----------------+ +| mysql | stable | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| namestore | n/a | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| nat | n/a | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| nse | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| peerinfo | n/a | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| psyc | experimental | experimental | experimental | ++-----------------+-----------------+-----------------+-----------------+ +| pt | n/a | n/a | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| regex | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| revocation | stable | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| social | experimental | experimental | experimental | ++-----------------+-----------------+-----------------+-----------------+ +| statistics | n/a | stable | stable | ++-----------------+-----------------+-----------------+-----------------+ +| testbed | n/a | testing | testing | ++-----------------+-----------------+-----------------+-----------------+ +| testing | n/a | n/a | testing | ++-----------------+-----------------+-----------------+-----------------+ +| topology | n/a | n/a | n/a | ++-----------------+-----------------+-----------------+-----------------+ +| transport | experimental | experimental | experimental | ++-----------------+-----------------+-----------------+-----------------+ +| tun | n/a | n/a | stable | ++-----------------+-----------------+-----------------+-----------------+ +| vpn | testing | n/a | n/a | ++-----------------+-----------------+-----------------+-----------------+ + +Here is a rough explanation of the values: + +.. todo:: 0.10.x is outdated - rewrite "\ ``stable``\ " to reflect + a time-independent meaning. + +'\ ``stable``\ ' + No incompatible changes are planned at this time; for IPC/APIs, if + there are incompatible changes, they will be minor and might only + require minimal changes to existing code; for P2P, changes will be + avoided if at all possible for the 0.10.x-series + +'\ ``testing``\ ' + No incompatible changes are planned at this time, but the code is + still known to be in flux; so while we have no concrete plans, our + expectation is that there will still be minor modifications; for P2P, + changes will likely be extensions that should not break existing code + +'\ ``unstable``\ ' + Changes are planned and will happen; however, they will not be + totally radical and the result should still resemble what is there + now; nevertheless, anticipated changes will break protocol/API + compatibility + +'\ ``experimental``\ ' + Changes are planned and the result may look nothing like what the + API/protocol looks like today + +'\ ``unknown``\ ' + Someone should think about where this subsystem headed + +'\ ``n/a``\ ' + This subsystem does not implement a corresponding API/protocol diff --git a/man_developers/subsystems/statistics/statistics.rst b/man_developers/subsystems/statistics/statistics.rst @@ -0,0 +1,192 @@ + +.. index:: + double: STATISTICS; subsystem + +.. _STATISTICS-Subsystem: + +STATISTICS — Runtime statistics publication +=========================================== + +In GNUnet, the STATISTICS subsystem offers a central place for all +subsystems to publish unsigned 64-bit integer run-time statistics. +Keeping this information centrally means that there is a unified way for +the user to obtain data on all subsystems, and individual subsystems do +not have to always include a custom data export method for performance +metrics and other statistics. For example, the TRANSPORT system uses +STATISTICS to update information about the number of directly connected +peers and the bandwidth that has been consumed by the various plugins. +This information is valuable for diagnosing connectivity and performance +issues. + +Following the GNUnet service architecture, the STATISTICS subsystem is +divided into an API which is exposed through the header +**gnunet_statistics_service.h** and the STATISTICS service +**gnunet-service-statistics**. The **gnunet-statistics** command-line +tool can be used to obtain (and change) information about the values +stored by the STATISTICS service. The STATISTICS service does not +communicate with other peers. + +Data is stored in the STATISTICS service in the form of tuples +**(subsystem, name, value, persistence)**. The subsystem determines to +which other GNUnet's subsystem the data belongs. name is the name +through which value is associated. It uniquely identifies the record +from among other records belonging to the same subsystem. In some parts +of the code, the pair **(subsystem, name)** is called a **statistic** as +it identifies the values stored in the STATISTCS service.The persistence +flag determines if the record has to be preserved across service +restarts. A record is said to be persistent if this flag is set for it; +if not, the record is treated as a non-persistent record and it is lost +after service restart. Persistent records are written to and read from +the file **statistics.data** before shutdown and upon startup. The file +is located in the HOME directory of the peer. + +An anomaly of the STATISTICS service is that it does not terminate +immediately upon receiving a shutdown signal if it has any clients +connected to it. It waits for all the clients that are not monitors to +close their connections before terminating itself. This is to prevent +the loss of data during peer shutdown — delaying the STATISTICS +service shutdown helps other services to store important data to +STATISTICS during shutdown. + +:index:`libgnunetstatistics <single: libgnunet; statistics>` +------------------------------------------------------------ + +**libgnunetstatistics** is the library containing the API for the +STATISTICS subsystem. Any process requiring to use STATISTICS should use +this API by to open a connection to the STATISTICS service. This is done +by calling the function ``GNUNET_STATISTICS_create()``. This function +takes the subsystem's name which is trying to use STATISTICS and a +configuration. All values written to STATISTICS with this connection +will be placed in the section corresponding to the given subsystem's +name. The connection to STATISTICS can be destroyed with the function +``GNUNET_STATISTICS_destroy()``. This function allows for the connection +to be destroyed immediately or upon transferring all pending write +requests to the service. + +Note: STATISTICS subsystem can be disabled by setting ``DISABLE = YES`` +under the ``[STATISTICS]`` section in the configuration. With such a +configuration all calls to ``GNUNET_STATISTICS_create()`` return +``NULL`` as the STATISTICS subsystem is unavailable and no other +functions from the API can be used. + +.. _Statistics-retrieval: + +Statistics retrieval +^^^^^^^^^^^^^^^^^^^^ + +Once a connection to the statistics service is obtained, information +about any other system which uses statistics can be retrieved with the +function GNUNET_STATISTICS_get(). This function takes the connection +handle, the name of the subsystem whose information we are interested in +(a ``NULL`` value will retrieve information of all available subsystems +using STATISTICS), the name of the statistic we are interested in (a +``NULL`` value will retrieve all available statistics), a continuation +callback which is called when all of requested information is retrieved, +an iterator callback which is called for each parameter in the retrieved +information and a closure for the aforementioned callbacks. The library +then invokes the iterator callback for each value matching the request. + +Call to ``GNUNET_STATISTICS_get()`` is asynchronous and can be canceled +with the function ``GNUNET_STATISTICS_get_cancel()``. This is helpful +when retrieving statistics takes too long and especially when we want to +shutdown and cleanup everything. + +.. _Setting-statistics-and-updating-them: + +Setting statistics and updating them +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +So far we have seen how to retrieve statistics, here we will learn how +we can set statistics and update them so that other subsystems can +retrieve them. + +A new statistic can be set using the function +``GNUNET_STATISTICS_set()``. This function takes the name of the +statistic and its value and a flag to make the statistic persistent. The +value of the statistic should be of the type ``uint64_t``. The function +does not take the name of the subsystem; it is determined from the +previous ``GNUNET_STATISTICS_create()`` invocation. If the given +statistic is already present, its value is overwritten. + +An existing statistics can be updated, i.e its value can be increased or +decreased by an amount with the function ``GNUNET_STATISTICS_update()``. +The parameters to this function are similar to +``GNUNET_STATISTICS_set()``, except that it takes the amount to be +changed as a type ``int64_t`` instead of the value. + +The library will combine multiple set or update operations into one +message if the client performs requests at a rate that is faster than +the available IPC with the STATISTICS service. Thus, the client does not +have to worry about sending requests too quickly. + +.. _Watches: + +Watches +^^^^^^^ + +As interesting feature of STATISTICS lies in serving notifications +whenever a statistic of our interest is modified. This is achieved by +registering a watch through the function ``GNUNET_STATISTICS_watch()``. +The parameters of this function are similar to those of +``GNUNET_STATISTICS_get()``. Changes to the respective statistic's value +will then cause the given iterator callback to be called. Note: A watch +can only be registered for a specific statistic. Hence the subsystem +name and the parameter name cannot be ``NULL`` in a call to +``GNUNET_STATISTICS_watch()``. + +A registered watch will keep notifying any value changes until +``GNUNET_STATISTICS_watch_cancel()`` is called with the same parameters +that are used for registering the watch. + +.. _The-STATISTICS-Client_002dService-Protocol: + +The STATISTICS Client-Service Protocol +-------------------------------------- + +.. _Statistics-retrieval2: + +Statistics retrieval +^^^^^^^^^^^^^^^^^^^^ + +To retrieve statistics, the client transmits a message of type +``GNUNET_MESSAGE_TYPE_STATISTICS_GET`` containing the given subsystem +name and statistic parameter to the STATISTICS service. The service +responds with a message of type ``GNUNET_MESSAGE_TYPE_STATISTICS_VALUE`` +for each of the statistics parameters that match the client request for +the client. The end of information retrieved is signaled by the service +by sending a message of type ``GNUNET_MESSAGE_TYPE_STATISTICS_END``. + +.. _Setting-and-updating-statistics: + +Setting and updating statistics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The subsystem name, parameter name, its value and the persistence flag +are communicated to the service through the message +``GNUNET_MESSAGE_TYPE_STATISTICS_SET``. + +When the service receives a message of type +``GNUNET_MESSAGE_TYPE_STATISTICS_SET``, it retrieves the subsystem name +and checks for a statistic parameter with matching the name given in the +message. If a statistic parameter is found, the value is overwritten by +the new value from the message; if not found then a new statistic +parameter is created with the given name and value. + +In addition to just setting an absolute value, it is possible to perform +a relative update by sending a message of type +``GNUNET_MESSAGE_TYPE_STATISTICS_SET`` with an update flag +(``GNUNET_STATISTICS_SETFLAG_RELATIVE``) signifying that the value in +the message should be treated as an update value. + +.. _Watching-for-updates: + +Watching for updates +^^^^^^^^^^^^^^^^^^^^ + +The function registers the watch at the service by sending a message of +type ``GNUNET_MESSAGE_TYPE_STATISTICS_WATCH``. The service then sends +notifications through messages of type +``GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE`` whenever the statistic +parameter's value is changed. + + diff --git a/man_developers/subsystems/transport-ng/transport-ng.rst b/man_developers/subsystems/transport-ng/transport-ng.rst @@ -0,0 +1,258 @@ + +.. index:: + double: TRANSPORT Next Generation; subsystem + +.. _TRANSPORT_002dNG-Subsystem: + +TRANSPORT-NG — Next-generation transport management +=================================================== + +The current GNUnet TRANSPORT architecture is rooted in the GNUnet 0.4 +design of using plugins for the actual transmission operations and the +ATS subsystem to select a plugin and allocate bandwidth. The following +key issues have been identified with this design: + +- Bugs in one plugin can affect the TRANSPORT service and other + plugins. There is at least one open bug that affects sockets, where + the origin is difficult to pinpoint due to the large code base. + +- Relevant operating system default configurations often impose a limit + of 1024 file descriptors per process. Thus, one plugin may impact + other plugin's connectivity choices. + +- Plugins are required to offer bi-directional connectivity. However, + firewalls (incl. NAT boxes) and physical environments sometimes only + allow uni-directional connectivity, which then currently cannot be + utilized at all. + +- Distance vector routing was implemented in 209 but shortly afterwards + broken and due to the complexity of implementing it as a plugin and + dealing with the resource allocation consequences was never useful. + +- Most existing plugins communicate completely using cleartext, + exposing metad data (message size) and making it easy to fingerprint + and possibly block GNUnet traffic. + +- Various NAT traversal methods are not supported. + +- The service logic is cluttered with \"manipulation\" support code for + TESTBED to enable faking network characteristics like lossy + connections or firewewalls. + +- Bandwidth allocation is done in ATS, requiring the duplication of + state and resulting in much delayed allocation decisions. As a + result, often available bandwidth goes unused. Users are expected to + manually configure bandwidth limits, instead of TRANSPORT using + congestion control to adapt automatically. + +- TRANSPORT is difficult to test and has bad test coverage. + +- HELLOs include an absolute expiration time. Nodes with unsynchronized + clocks cannot connect. + +- Displaying the contents of a HELLO requires the respective plugin as + the plugin-specific data is encoded in binary. This also complicates + logging. + +.. _Design-goals-of-TNG: + +Design goals of TNG +------------------- + +In order to address the above issues, we want to: + +- Move plugins into separate processes which we shall call + *communicators*. Communicators connect as clients to the transport + service. + +- TRANSPORT should be able to utilize any number of communcators to the + same peer at the same time. + +- TRANSPORT should be responsible for fragmentation, retransmission, + flow- and congestion-control. Users should no longer have to + configure bandwidth limits: TRANSPORT should detect what is available + and use it. + +- Commnunicators should be allowed to be uni-directional and + unreliable. TRANSPORT shall create bi-directional channels from this + whenever possible. + +- DV should no longer be a plugin, but part of TRANSPORT. + +- TRANSPORT should provide communicators help communicating, for + example in the case of uni-directional communicators or the need for + out-of-band signalling for NAT traversal. We call this functionality + *backchannels*. + +- Transport manipulation should be signalled to CORE on a per-message + basis instead of an approximate bandwidth. + +- CORE should signal performance requirements (reliability, latency, + etc.) on a per-message basis to TRANSPORT. If possible, TRANSPORT + should consider those options when scheduling messages for + transmission. + +- HELLOs should be in a humman-readable format with monotonic time + expirations. + +The new architecture is planned as follows: + +.. image:: /_static/images/tng.png + +TRANSPORT's main objective is to establish bi-directional virtual links +using a variety of possibly uni-directional communicators. Links undergo +the following steps: + +1. Communicator informs TRANSPORT A that a queue (direct neighbour) is + available, or equivalently TRANSPORT A discovers a (DV) path to a + target B. + +2. TRANSPORT A sends a challenge to the target peer, trying to confirm + that the peer can receive. FIXME: This is not implemented properly + for DV. Here we should really take a validated DVH and send a + challenge exactly down that path! + +3. The other TRANSPORT, TRANSPORT B, receives the challenge, and sends + back a response, possibly using a dierent path. If TRANSPORT B does + not yet have a virtual link to A, it must try to establish a virtual + link. + +4. Upon receiving the response, TRANSPORT A creates the virtual link. If + the response included a challenge, TRANSPORT A must respond to this + challenge as well, eectively re-creating the TCP 3-way handshake + (just with longer challenge values). + +.. _HELLO_002dNG: + +HELLO-NG +-------- + +HELLOs change in three ways. First of all, communicators encode the +respective addresses in a human-readable URL-like string. This way, we +do no longer require the communicator to print the contents of a HELLO. +Second, HELLOs no longer contain an expiration time, only a creation +time. The receiver must only compare the respective absolute values. So +given a HELLO from the same sender with a larger creation time, then the +old one is no longer valid. This also obsoletes the need for the +gnunet-hello binary to set HELLO expiration times to never. Third, a +peer no longer generates one big HELLO that always contains all of the +addresses. Instead, each address is signed individually and shared only +over the address scopes where it makes sense to share the address. In +particular, care should be taken to not share MACs across the Internet +and confine their use to the LAN. As each address is signed separately, +having multiple addresses valid at the same time (given the new creation +time expiration logic) requires that those addresses must have exactly +the same creation time. Whenever that monotonic time is increased, all +addresses must be re-signed and re-distributed. + +.. _Priorities-and-preferences: + +Priorities and preferences +-------------------------- + +In the new design, TRANSPORT adopts a feature (which was previously +already available in CORE) of the MQ API to allow applications to +specify priorities and preferences per message (or rather, per MQ +envelope). The (updated) MQ API allows applications to specify one of +four priority levels as well as desired preferences for transmission by +setting options on an envelope. These preferences currently are: + +- GNUNET_MQ_PREF_UNRELIABLE: Disables TRANSPORT waiting for ACKS on + unreliable channels like UDP. Now it is fire and forget. These + messages then cannot be used for RTT estimates either. + +- GNUNET_MQ_PREF_LOW_LATENCY: Directs TRANSPORT to select the + lowest-latency transmission choices possible. + +- GNUNET_MQ_PREF_CORK_ALLOWED: Allows TRANSPORT to delay transmission + to group the message with other messages into a larger batch to + reduce the number of packets sent. + +- GNUNET_MQ_PREF_GOODPUT: Directs TRANSPORT to select the highest + goodput channel available. + +- GNUNET_MQ_PREF_OUT_OF_ORDER: Allows TRANSPORT to reorder the messages + as it sees fit, otherwise TRANSPORT should attempt to preserve + transmission order. + +Each MQ envelope is always able to store those options (and the +priority), and in the future this uniform API will be used by TRANSPORT, +CORE, CADET and possibly other subsystems that send messages (like +LAKE). When CORE sets preferences and priorities, it is supposed to +respect the preferences and priorities it is given from higher layers. +Similarly, CADET also simply passes on the preferences and priorities of +the layer above CADET. When a layer combines multiple smaller messages +into one larger transmission, the ``GNUNET_MQ_env_combine_options()`` +should be used to calculate options for the combined message. We note +that the exact semantics of the options may differ by layer. For +example, CADET will always strictly implement reliable and in-order +delivery of messages, while the same options are only advisory for +TRANSPORT and CORE: they should try (using ACKs on unreliable +communicators, not changing the message order themselves), but if +messages are lost anyway (e.g. because a TCP is dropped in the middle), +or if messages are reordered (e.g. because they took different paths +over the network and arrived in a different order) TRANSPORT and CORE do +not have to correct this. Whether a preference is strict or loose is +thus dened by the respective layer. + +.. _Communicators: + +Communicators +------------- + +The API for communicators is defined in +``gnunet_transport_communication_service.h``. Each communicator must +specify its (global) communication characteristics, which for now only +say whether the communication is reliable (e.g. TCP, HTTPS) or +unreliable (e.g. UDP, WLAN). Each communicator must specify a unique +address prex, or NULL if the communicator cannot establish outgoing +connections (for example because it is only acting as a TCP server). A +communicator must tell TRANSPORT which addresses it is reachable under. +Addresses may be added or removed at any time. A communicator may have +zero addresses (transmission only). Addresses do not have to match the +address prefix. + +TRANSPORT may ask a communicator to try to connect to another address. +TRANSPORT will only ask for connections where the address matches the +communicator's address prefix that was provided when the connection was +established. Communicators should then attempt to establish a +connection. No response is provided to TRANSPORT service on failure. The +TRANSPORT service has to ask the communicator explicitly to retry. + +If a communicator succeeds in establishing an outgoing connection for +transmission, or if a communicator receives an incoming bi-directional +connection, the communicator must inform the TRANSPORT service that a +message queue (MQ) for transmission is now available. For that MQ, the +communicator must provide the peer identity claimed by the other end, a +human-readable address (for debugging) and a maximum transfer unit +(MTU). A MTU of zero means sending is not supported, SIZE_MAX should be +used for no MTU. The communicator should also tell TRANSPORT what +network type is used for the queue. The communicator may tell TRANSPORT +anytime that the queue was deleted and is no longer available. + +The communicator API also provides for flow control. First, +communicators exhibit back-pressure on TRANSPORT: the number of messages +TRANSPORT may add to a queue for transmission will be limited. So by not +draining the transmission queue, back-pressure is provided to TRANSPORT. +In the other direction, communicators may allow TRANSPORT to give +back-pressure towards the communicator by providing a non-NULL +``GNUNET_TRANSPORT_MessageCompletedCallback`` argument to the +``GNUNET_TRANSPORT_communicator_receive`` function. In this case, +TRANSPORT will only invoke this function once it has processed the +message and is ready to receive more. Communicators should then limit +how much traffic they receive based on this backpressure. Note that +communicators do not have to provide a +``GNUNET_TRANSPORT_MessageCompletedCallback``; for example, UDP cannot +support back-pressure due to the nature of the UDP protocol. In this +case, TRANSPORT will implement its own TRANSPORT-to-TRANSPORT flow +control to reduce the sender's data rate to acceptable levels. + +TRANSPORT may notify a communicator about backchannel messages TRANSPORT +received from other peers for this communicator. Similarly, +communicators can ask TRANSPORT to try to send a backchannel message to +other communicators of other peers. The semantics of the backchannel +message are up to the communicators which use them. TRANSPORT may fail +transmitting backchannel messages, and TRANSPORT will not attempt to +retransmit them. + + diff --git a/man_developers/subsystems/transport/transport.rst b/man_developers/subsystems/transport/transport.rst @@ -0,0 +1,843 @@ +.. index:: + double: TRANSPORT; subsystem + +.. _TRANSPORT-Subsystem: + +TRANSPORT — Overlay transport management +======================================== + +This chapter documents how the GNUnet transport subsystem works. The +GNUnet transport subsystem consists of three main components: the +transport API (the interface used by the rest of the system to access +the transport service), the transport service itself (most of the +interesting functions, such as choosing transports, happens here) and +the transport plugins. A transport plugin is a concrete implementation +for how two GNUnet peers communicate; many plugins exist, for example +for communication via TCP, UDP, HTTP, HTTPS and others. Finally, the +transport subsystem uses supporting code, especially the NAT/UPnP +library to help with tasks such as NAT traversal. + +Key tasks of the transport service include: + +- Create our HELLO message, notify clients and neighbours if our HELLO + changes (using NAT library as necessary) + +- Validate HELLOs from other peers (send PING), allow other peers to + validate our HELLO's addresses (send PONG) + +- Upon request, establish connections to other peers (using address + selection from ATS subsystem) and maintain them (again using PINGs + and PONGs) as long as desired + +- Accept incoming connections, give ATS service the opportunity to + switch communication channels + +- Notify clients about peers that have connected to us or that have + been disconnected from us + +- If a (stateful) connection goes down unexpectedly (without explicit + DISCONNECT), quickly attempt to recover (without notifying clients) + but do notify clients quickly if reconnecting fails + +- Send (payload) messages arriving from clients to other peers via + transport plugins and receive messages from other peers, forwarding + those to clients + +- Enforce inbound traffic limits (using flow-control if it is + applicable); outbound traffic limits are enforced by CORE, not by us + (!) + +- Enforce restrictions on P2P connection as specified by the blacklist + configuration and blacklisting clients + +Note that the term \"clients\" in the list above really refers to the +GNUnet-CORE service, as CORE is typically the only client of the +transport service. + +.. _Address-validation-protocol: + +Address validation protocol +--------------------------- + +This section documents how the GNUnet transport service validates +connections with other peers. It is a high-level description of the +protocol necessary to understand the details of the implementation. It +should be noted that when we talk about PING and PONG messages in this +section, we refer to transport-level PING and PONG messages, which are +different from core-level PING and PONG messages (both in implementation +and function). + +The goal of transport-level address validation is to minimize the +chances of a successful man-in-the-middle attack against GNUnet peers on +the transport level. Such an attack would not allow the adversary to +decrypt the P2P transmissions, but a successful attacker could at least +measure traffic volumes and latencies (raising the adversaries +capabilities by those of a global passive adversary in the worst case). +The scenarios we are concerned about is an attacker, Mallory, giving a +``HELLO`` to Alice that claims to be for Bob, but contains Mallory's IP +address instead of Bobs (for some transport). Mallory would then forward +the traffic to Bob (by initiating a connection to Bob and claiming to be +Alice). As a further complication, the scheme has to work even if say +Alice is behind a NAT without traversal support and hence has no address +of her own (and thus Alice must always initiate the connection to Bob). + +An additional constraint is that ``HELLO`` messages do not contain a +cryptographic signature since other peers must be able to edit (i.e. +remove) addresses from the ``HELLO`` at any time (this was not true in +GNUnet 0.8.x). A basic **assumption** is that each peer knows the set of +possible network addresses that it **might** be reachable under (so for +example, the external IP address of the NAT plus the LAN address(es) +with the respective ports). + +The solution is the following. If Alice wants to validate that a given +address for Bob is valid (i.e. is actually established **directly** with +the intended target), she sends a PING message over that connection to +Bob. Note that in this case, Alice initiated the connection so only +Alice knows which address was used for sure (Alice may be behind NAT, so +whatever address Bob sees may not be an address Alice knows she has). +Bob checks that the address given in the ``PING`` is actually one of +Bob's addresses (ie: does not belong to Mallory), and if it is, sends +back a ``PONG`` (with a signature that says that Bob owns/uses the +address from the ``PING``). Alice checks the signature and is happy if +it is valid and the address in the ``PONG`` is the address Alice used. +This is similar to the 0.8.x protocol where the ``HELLO`` contained a +signature from Bob for each address used by Bob. Here, the purpose code +for the signature is ``GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN``. +After this, Alice will remember Bob's address and consider the address +valid for a while (12h in the current implementation). Note that after +this exchange, Alice only considers Bob's address to be valid, the +connection itself is not considered 'established'. In particular, Alice +may have many addresses for Bob that Alice considers valid. + +The ``PONG`` message is protected with a nonce/challenge against replay +attacks (`replay <http://en.wikipedia.org/wiki/Replay_attack>`__) and +uses an expiration time for the signature (but those are almost +implementation details). + +NAT library +.. _NAT-library: + +NAT library +----------- + +The goal of the GNUnet NAT library is to provide a general-purpose API +for NAT traversal **without** third-party support. So protocols that +involve contacting a third peer to help establish a connection between +two peers are outside of the scope of this API. That does not mean that +GNUnet doesn't support involving a third peer (we can do this with the +distance-vector transport or using application-level protocols), it just +means that the NAT API is not concerned with this possibility. The API +is written so that it will work for IPv6-NAT in the future as well as +current IPv4-NAT. Furthermore, the NAT API is always used, even for +peers that are not behind NAT --- in that case, the mapping provided is +simply the identity. + +NAT traversal is initiated by calling ``GNUNET_NAT_register``. Given a +set of addresses that the peer has locally bound to (TCP or UDP), the +NAT library will return (via callback) a (possibly longer) list of +addresses the peer **might** be reachable under. Internally, depending +on the configuration, the NAT library will try to punch a hole (using +UPnP) or just \"know\" that the NAT was manually punched and generate +the respective external IP address (the one that should be globally +visible) based on the given information. + +The NAT library also supports ICMP-based NAT traversal. Here, the other +peer can request connection-reversal by this peer (in this special case, +the peer is even allowed to configure a port number of zero). If the NAT +library detects a connection-reversal request, it returns the respective +target address to the client as well. It should be noted that +connection-reversal is currently only intended for TCP, so other plugins +**must** pass ``NULL`` for the reversal callback. Naturally, the NAT +library also supports requesting connection reversal from a remote peer +(``GNUNET_NAT_run_client``). + +Once initialized, the NAT handle can be used to test if a given address +is possibly a valid address for this peer (``GNUNET_NAT_test_address``). +This is used for validating our addresses when generating PONGs. + +Finally, the NAT library contains an API to test if our NAT +configuration is correct. Using ``GNUNET_NAT_test_start`` **before** +binding to the respective port, the NAT library can be used to test if +the configuration works. The test function act as a local client, +initialize the NAT traversal and then contact a ``gnunet-nat-server`` +(running by default on ``gnunet.org``) and ask for a connection to be +established. This way, it is easy to test if the current NAT +configuration is valid. + +.. _Distance_002dVector-plugin: + +Distance-Vector plugin +---------------------- + +The Distance Vector (DV) transport is a transport mechanism that allows +peers to act as relays for each other, thereby connecting peers that +would otherwise be unable to connect. This gives a larger connection set +to applications that may work better with more peers to choose from (for +example, File Sharing and/or DHT). + +The Distance Vector transport essentially has two functions. The first +is \"gossiping\" connection information about more distant peers to +directly connected peers. The second is taking messages intended for +non-directly connected peers and encapsulating them in a DV wrapper that +contains the required information for routing the message through +forwarding peers. Via gossiping, optimal routes through the known DV +neighborhood are discovered and utilized and the message encapsulation +provides some benefits in addition to simply getting the message from +the correct source to the proper destination. + +The gossiping function of DV provides an up to date routing table of +peers that are available up to some number of hops. We call this a +fisheye view of the network (like a fish, nearby objects are known while +more distant ones unknown). Gossip messages are sent only to directly +connected peers, but they are sent about other knowns peers within the +\"fisheye distance\". Whenever two peers connect, they immediately +gossip to each other about their appropriate other neighbors. They also +gossip about the newly connected peer to previously connected neighbors. +In order to keep the routing tables up to date, disconnect notifications +are propagated as gossip as well (because disconnects may not be +sent/received, timeouts are also used remove stagnant routing table +entries). + +Routing of messages via DV is straightforward. When the DV transport is +notified of a message destined for a non-direct neighbor, the +appropriate forwarding peer is selected, and the base message is +encapsulated in a DV message which contains information about the +initial peer and the intended recipient. At each forwarding hop, the +initial peer is validated (the forwarding peer ensures that it has the +initial peer in its neighborhood, otherwise the message is dropped). +Next the base message is re-encapsulated in a new DV message for the +next hop in the forwarding chain (or delivered to the current peer, if +it has arrived at the destination). + +Assume a three peer network with peers Alice, Bob and Carol. Assume that + +:: + + Alice <-> Bob and Bob <-> Carol + +are direct (e.g. over TCP or UDP transports) connections, but that Alice +cannot directly connect to Carol. This may be the case due to NAT or +firewall restrictions, or perhaps based on one of the peers respective +configurations. If the Distance Vector transport is enabled on all three +peers, it will automatically discover (from the gossip protocol) that +Alice and Carol can connect via Bob and provide a \"virtual\" Alice <-> +Carol connection. Routing between Alice and Carol happens as follows; +Alice creates a message destined for Carol and notifies the DV transport +about it. The DV transport at Alice looks up Carol in the routing table +and finds that the message must be sent through Bob for Carol. The +message is encapsulated setting Alice as the initiator and Carol as the +destination and sent to Bob. Bob receives the messages, verifies that +both Alice and Carol are known to Bob, and re-wraps the message in a new +DV message for Carol. The DV transport at Carol receives this message, +unwraps the original message, and delivers it to Carol as though it came +directly from Alice. + +SMTP plugin +.. _SMTP-plugin: + +SMTP plugin +----------- + +.. todo:: Update? + +This section describes the new SMTP transport plugin for GNUnet as it +exists in the 0.7.x and 0.8.x branch. SMTP support is currently not +available in GNUnet 0.9.x. This page also describes the transport layer +abstraction (as it existed in 0.7.x and 0.8.x) in more detail and gives +some benchmarking results. The performance results presented are quite +old and maybe outdated at this point. For the readers in the year 2019, +you will notice by the mention of version 0.7, 0.8, and 0.9 that this +section has to be taken with your usual grain of salt and be updated +eventually. + +- Why use SMTP for a peer-to-peer transport? + +- SMTPHow does it work? + +- How do I configure my peer? + +- How do I test if it works? + +- How fast is it? + +- Is there any additional documentation? + +.. _Why-use-SMTP-for-a-peer_002dto_002dpeer-transport_003f: + +Why use SMTP for a peer-to-peer transport? +------------------------------------------ + +There are many reasons why one would not want to use SMTP: + +- SMTP is using more bandwidth than TCP, UDP or HTTP + +- SMTP has a much higher latency. + +- SMTP requires significantly more computation (encoding and decoding + time) for the peers. + +- SMTP is significantly more complicated to configure. + +- SMTP may be abused by tricking GNUnet into sending mail + to non-participating third parties. + +So why would anybody want to use SMTP? + +- SMTP can be used to contact peers behind NAT boxes (in virtual + private networks). + +- SMTP can be used to circumvent policies that limit or prohibit + peer-to-peer traffic by masking as \"legitimate\" traffic. + +- SMTP uses E-mail addresses which are independent of a specific IP, + which can be useful to address peers that use dynamic IP addresses. + +- SMTP can be used to initiate a connection (e.g. initial address + exchange) and peers can then negotiate the use of a more efficient + protocol (e.g. TCP) for the actual communication. + +In summary, SMTP can for example be used to send a message to a peer +behind a NAT box that has a dynamic IP to tell the peer to establish a +TCP connection to a peer outside of the private network. Even an +extraordinary overhead for this first message would be irrelevant in +this type of situation. + +.. _How-does-it-work_003f: + +How does it work? +----------------- + +When a GNUnet peer needs to send a message to another GNUnet peer that +has advertised (only) an SMTP transport address, GNUnet base64-encodes +the message and sends it in an E-mail to the advertised address. The +advertisement contains a filter which is placed in the E-mail header, +such that the receiving host can filter the tagged E-mails and forward +it to the GNUnet peer process. The filter can be specified individually +by each peer and be changed over time. This makes it impossible to +censor GNUnet E-mail messages by searching for a generic filter. + +.. _How-do-I-configure-my-peer_003f: + +How do I configure my peer? +--------------------------- + +First, you need to configure ``procmail`` to filter your inbound E-mail +for GNUnet traffic. The GNUnet messages must be delivered into a pipe, +for example ``/tmp/gnunet.smtp``. You also need to define a filter that +is used by ``procmail`` to detect GNUnet messages. You are free to +choose whichever filter you like, but you should make sure that it does +not occur in your other E-mail. In our example, we will use +``X-mailer: GNUnet``. The ``~/.procmailrc`` configuration file then +looks like this: + +:: + + :0: + * ^X-mailer: GNUnet + /tmp/gnunet.smtp + # where do you want your other e-mail delivered to + # (default: /var/spool/mail/) + :0: /var/spool/mail/ + +After adding this file, first make sure that your regular E-mail still +works (e.g. by sending an E-mail to yourself). Then edit the GNUnet +configuration. In the section ``SMTP`` you need to specify your E-mail +address under ``EMAIL``, your mail server (for outgoing mail) under +``SERVER``, the filter (X-mailer: GNUnet in the example) under +``FILTER`` and the name of the pipe under ``PIPE``. The completed +section could then look like this: + +.. code-block:: text + + EMAIL = me@mail.gnu.org MTU = 65000 SERVER = mail.gnu.org:25 FILTER = + "X-mailer: GNUnet" PIPE = /tmp/gnunet.smtp + +.. todo:: set highlighting for this code block properly. + +Finally, you need to add ``smtp`` to the list of ``TRANSPORTS`` in the +``GNUNETD`` section. GNUnet peers will use the E-mail address that you +specified to contact your peer until the advertisement times out. Thus, +if you are not sure if everything works properly or if you are not +planning to be online for a long time, you may want to configure this +timeout to be short, e.g. just one hour. For this, set ``HELLOEXPIRES`` +to ``1`` in the ``GNUNETD`` section. + +This should be it, but you may probably want to test it first. + +.. _How-do-I-test-if-it-works_003f: + +How do I test if it works? +-------------------------- + +Any transport can be subjected to some rudimentary tests using the +``gnunet-transport-check`` tool. The tool sends a message to the local +node via the transport and checks that a valid message is received. +While this test does not involve other peers and can not check if +firewalls or other network obstacles prohibit proper operation, this is +a great testcase for the SMTP transport since it tests pretty much +nearly all of the functionality. + +``gnunet-transport-check`` should only be used without running +``gnunetd`` at the same time. By default, ``gnunet-transport-check`` +tests all transports that are specified in the configuration file. But +you can specifically test SMTP by giving the option +``--transport=smtp``. + +Note that this test always checks if a transport can receive and send. +While you can configure most transports to only receive or only send +messages, this test will only work if you have configured the transport +to send and receive messages. + +.. _How-fast-is-it_003f: + +How fast is it? +--------------- + +We have measured the performance of the UDP, TCP and SMTP transport +layer directly and when used from an application using the GNUnet core. +Measuring just the transport layer gives the better view of the actual +overhead of the protocol, whereas evaluating the transport from the +application puts the overhead into perspective from a practical point of +view. + +The loopback measurements of the SMTP transport were performed on three +different machines spanning a range of modern SMTP configurations. We +used a PIII-800 running RedHat 7.3 with the Purdue Computer Science +configuration which includes filters for spam. We also used a Xenon 2 +GHZ with a vanilla RedHat 8.0 sendmail configuration. Furthermore, we +used qmail on a PIII-1000 running Sorcerer GNU Linux (SGL). The numbers +for UDP and TCP are provided using the SGL configuration. The qmail +benchmark uses qmail's internal filtering whereas the sendmail +benchmarks relies on procmail to filter and deliver the mail. We used +the transport layer to send a message of b bytes (excluding transport +protocol headers) directly to the local machine. This way, network +latency and packet loss on the wire have no impact on the timings. n +messages were sent sequentially over the transport layer, sending +message i+1 after the i-th message was received. All messages were sent +over the same connection and the time to establish the connection was +not taken into account since this overhead is minuscule in practice --- +as long as a connection is used for a significant number of messages. + ++--------------+----------+----------+----------+----------+----------+ +| Transport | UDP | TCP | SMTP | SMTP (RH | SMTP | +| | | | (Purdue | 8.0) | (SGL | +| | | | s | | qmail) | +| | | | endmail) | | | ++==============+==========+==========+==========+==========+==========+ +| 11 bytes | 31 ms | 55 ms | 781 s | 77 s | 24 s | ++--------------+----------+----------+----------+----------+----------+ +| 407 bytes | 37 ms | 62 ms | 789 s | 78 s | 25 s | ++--------------+----------+----------+----------+----------+----------+ +| 1,221 bytes | 46 ms | 73 ms | 804 s | 78 s | 25 s | ++--------------+----------+----------+----------+----------+----------+ + +The benchmarks show that UDP and TCP are, as expected, both +significantly faster compared with any of the SMTP services. Among the +SMTP implementations, there can be significant differences depending on +the SMTP configuration. Filtering with an external tool like procmail +that needs to re-parse its configuration for each mail can be very +expensive. Applying spam filters can also significantly impact the +performance of the underlying SMTP implementation. The microbenchmark +shows that SMTP can be a viable solution for initiating peer-to-peer +sessions: a couple of seconds to connect to a peer are probably not even +going to be noticed by users. The next benchmark measures the possible +throughput for a transport. Throughput can be measured by sending +multiple messages in parallel and measuring packet loss. Note that not +only UDP but also the TCP transport can actually loose messages since +the TCP implementation drops messages if the ``write`` to the socket +would block. While the SMTP protocol never drops messages itself, it is +often so slow that only a fraction of the messages can be sent and +received in the given time-bounds. For this benchmark we report the +message loss after allowing t time for sending m messages. If messages +were not sent (or received) after an overall timeout of t, they were +considered lost. The benchmark was performed using two Xeon 2 GHZ +machines running RedHat 8.0 with sendmail. The machines were connected +with a direct 100 MBit Ethernet connection. Figures udp1200, tcp1200 and +smtp-MTUs show that the throughput for messages of size 1,200 octets is +2,343 kbps, 3,310 kbps and 6 kbps for UDP, TCP and SMTP respectively. +The high per-message overhead of SMTP can be improved by increasing the +MTU, for example, an MTU of 12,000 octets improves the throughput to 13 +kbps as figure smtp-MTUs shows. Our research paper [Transport2014]_ has +some more details on the benchmarking results. + +Bluetooth plugin +.. _Bluetooth-plugin: + +Bluetooth plugin +---------------- + +This page describes the new Bluetooth transport plugin for GNUnet. The +plugin is still in the testing stage so don't expect it to work +perfectly. If you have any questions or problems just post them here or +ask on the IRC channel. + +- What do I need to use the Bluetooth plugin transport? + +- BluetoothHow does it work? + +- What possible errors should I be aware of? + +- How do I configure my peer? + +- How can I test it? + +.. _What-do-I-need-to-use-the-Bluetooth-plugin-transport_003f: + +What do I need to use the Bluetooth plugin transport? +----------------------------------------------------- + +If you are a GNU/Linux user and you want to use the Bluetooth transport +plugin you should install the ``BlueZ`` development libraries (if they +aren't already installed). For instructions about how to install the +libraries you should check out the BlueZ site +(`http://www.bluez.org <http://www.bluez.org/>`__). If you don't know if +you have the necessary libraries, don't worry, just run the GNUnet +configure script and you will be able to see a notification at the end +which will warn you if you don't have the necessary libraries. + +.. _How-does-it-work2_003f: + +.. todo:: Change to unique title? + +How does it work2? +------------------ + +The Bluetooth transport plugin uses virtually the same code as the WLAN +plugin and only the helper binary is different. The helper takes a +single argument, which represents the interface name and is specified in +the configuration file. Here are the basic steps that are followed by +the helper binary used on GNU/Linux: + +- it verifies if the name corresponds to a Bluetooth interface name + +- it verifies if the interface is up (if it is not, it tries to bring + it up) + +- it tries to enable the page and inquiry scan in order to make the + device discoverable and to accept incoming connection requests *The + above operations require root access so you should start the + transport plugin with root privileges.* + +- it finds an available port number and registers a SDP service which + will be used to find out on which port number is the server listening + on and switch the socket in listening mode + +- it sends a HELLO message with its address + +- finally it forwards traffic from the reading sockets to the STDOUT + and from the STDIN to the writing socket + +Once in a while the device will make an inquiry scan to discover the +nearby devices and it will send them randomly HELLO messages for peer +discovery. + +.. _What-possible-errors-should-I-be-aware-of_003f: + +What possible errors should I be aware of? +------------------------------------------ + +*This section is dedicated for GNU/Linux users* + +Well there are many ways in which things could go wrong but I will try +to present some tools that you could use to debug and some scenarios. + +- ``bluetoothd -n -d`` : use this command to enable logging in the + foreground and to print the logging messages + +- ``hciconfig``: can be used to configure the Bluetooth devices. If you + run it without any arguments it will print information about the + state of the interfaces. So if you receive an error that the device + couldn't be brought up you should try to bring it manually and to see + if it works (use ``hciconfig -a hciX up``). If you can't and the + Bluetooth address has the form 00:00:00:00:00:00 it means that there + is something wrong with the D-Bus daemon or with the Bluetooth + daemon. Use ``bluetoothd`` tool to see the logs + +- ``sdptool`` can be used to control and interrogate SDP servers. If + you encounter problems regarding the SDP server (like the SDP server + is down) you should check out if the D-Bus daemon is running + correctly and to see if the Bluetooth daemon started correctly(use + ``bluetoothd`` tool). Also, sometimes the SDP service could work but + somehow the device couldn't register its service. Use + ``sdptool browse [dev-address]`` to see if the service is registered. + There should be a service with the name of the interface and GNUnet + as provider. + +- ``hcitool`` : another useful tool which can be used to configure the + device and to send some particular commands to it. + +- ``hcidump`` : could be used for low level debugging + +.. _How-do-I-configure-my-peer2_003f: + +.. todo:: Fix name/referencing now that we're using Sphinx. + +How do I configure my peer2? +---------------------------- + +On GNU/Linux, you just have to be sure that the interface name +corresponds to the one that you want to use. Use the ``hciconfig`` tool +to check that. By default it is set to hci0 but you can change it. + +A basic configuration looks like this: + +:: + + [transport-bluetooth] + # Name of the interface (typically hciX) + INTERFACE = hci0 + # Real hardware, no testing + TESTMODE = 0 TESTING_IGNORE_KEYS = ACCEPT_FROM; + +In order to use the Bluetooth transport plugin when the transport +service is started, you must add the plugin name to the default +transport service plugins list. For example: + +:: + + [transport] ... PLUGINS = dns bluetooth ... + +If you want to use only the Bluetooth plugin set *PLUGINS = bluetooth* + +On Windows, you cannot specify which device to use. The only thing that +you should do is to add *bluetooth* on the plugins list of the transport +service. + +.. _How-can-I-test-it_003f: + +How can I test it? +------------------ + +If you have two Bluetooth devices on the same machine and you are using +GNU/Linux you must: + +- create two different file configuration (one which will use the first + interface (*hci0*) and the other which will use the second interface + (*hci1*)). Let's name them *peer1.conf* and *peer2.conf*. + +- run *gnunet-peerinfo -c peerX.conf -s* in order to generate the peers + private keys. The **X** must be replace with 1 or 2. + +- run *gnunet-arm -c peerX.conf -s -i=transport* in order to start the + transport service. (Make sure that you have \"bluetooth\" on the + transport plugins list if the Bluetooth transport service doesn't + start.) + +- run *gnunet-peerinfo -c peer1.conf -s* to get the first peer's ID. If + you already know your peer ID (you saved it from the first command), + this can be skipped. + +- run *gnunet-transport -c peer2.conf -p=PEER1_ID -s* to start sending + data for benchmarking to the other peer. + +This scenario will try to connect the second peer to the first one and +then start sending data for benchmarking. + +If you have two different machines and your configuration files are good +you can use the same scenario presented on the beginning of this +section. + +Another way to test the plugin functionality is to create your own +application which will use the GNUnet framework with the Bluetooth +transport service. + +.. _The-implementation-of-the-Bluetooth-transport-plugin: + +The implementation of the Bluetooth transport plugin +---------------------------------------------------- + +This page describes the implementation of the Bluetooth transport +plugin. + +First I want to remind you that the Bluetooth transport plugin uses +virtually the same code as the WLAN plugin and only the helper binary is +different. Also the scope of the helper binary from the Bluetooth +transport plugin is the same as the one used for the WLAN transport +plugin: it accesses the interface and then it forwards traffic in both +directions between the Bluetooth interface and stdin/stdout of the +process involved. + +The Bluetooth plugin transport could be used both on GNU/Linux and +Windows platforms. + +- Linux functionality + +- Pending Features + +.. _Linux-functionality: + +Linux functionality +^^^^^^^^^^^^^^^^^^^ + +In order to implement the plugin functionality on GNU/Linux I used the +BlueZ stack. For the communication with the other devices I used the +RFCOMM protocol. Also I used the HCI protocol to gain some control over +the device. The helper binary takes a single argument (the name of the +Bluetooth interface) and is separated in two stages: + +.. _THE-INITIALIZATION: + +.. todo:: 'THE INITIALIZATION' should be in bigger letters or stand out, not + starting a new section? + +THE INITIALIZATION +^^^^^^^^^^^^^^^^^^ + +- first, it checks if we have root privileges (*Remember that we need + to have root privileges in order to be able to bring the interface up + if it is down or to change its state.*). + +- second, it verifies if the interface with the given name exists. + + **If the interface with that name exists and it is a Bluetooth + interface:** + +- it creates a RFCOMM socket which will be used for listening and call + the *open_device* method + + On the *open_device* method: + + - creates a HCI socket used to send control events to the device + + - searches for the device ID using the interface name + + - saves the device MAC address + + - checks if the interface is down and tries to bring it UP + + - checks if the interface is in discoverable mode and tries to make + it discoverable + + - closes the HCI socket and binds the RFCOMM one + + - switches the RFCOMM socket in listening mode + + - registers the SDP service (the service will be used by the other + devices to get the port on which this device is listening on) + +- drops the root privileges + + **If the interface is not a Bluetooth interface the helper exits with + a suitable error** + +.. _THE-LOOP: + +THE LOOP +^^^^^^^^ + +The helper binary uses a list where it saves all the connected neighbour +devices (*neighbours.devices*) and two buffers (*write_pout* and +*write_std*). The first message which is send is a control message with +the device's MAC address in order to announce the peer presence to the +neighbours. Here are a short description of what happens in the main +loop: + +- Every time when it receives something from the STDIN it processes the + data and saves the message in the first buffer (*write_pout*). When + it has something in the buffer, it gets the destination address from + the buffer, searches the destination address in the list (if there is + no connection with that device, it creates a new one and saves it to + the list) and sends the message. + +- Every time when it receives something on the listening socket it + accepts the connection and saves the socket on a list with the + reading sockets. + +- Every time when it receives something from a reading socket it parses + the message, verifies the CRC and saves it in the *write_std* buffer + in order to be sent later to the STDOUT. + +So in the main loop we use the select function to wait until one of the +file descriptor saved in one of the two file descriptors sets used is +ready to use. The first set (*rfds*) represents the reading set and it +could contain the list with the reading sockets, the STDIN file +descriptor or the listening socket. The second set (*wfds*) is the +writing set and it could contain the sending socket or the STDOUT file +descriptor. After the select function returns, we check which file +descriptor is ready to use and we do what is supposed to do on that kind +of event. *For example:* if it is the listening socket then we accept a +new connection and save the socket in the reading list; if it is the +STDOUT file descriptor, then we write to STDOUT the message from the +*write_std* buffer. + +To find out on which port a device is listening on we connect to the +local SDP server and search the registered service for that device. + +*You should be aware of the fact that if the device fails to connect to +another one when trying to send a message it will attempt one more time. +If it fails again, then it skips the message.* *Also you should know +that the transport Bluetooth plugin has support for*\ **broadcast +messages**\ *.* + +.. _Details-about-the-broadcast-implementation: + +Details about the broadcast implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First I want to point out that the broadcast functionality for the +CONTROL messages is not implemented in a conventional way. Since the +inquiry scan time is too big and it will take some time to send a +message to all the discoverable devices I decided to tackle the problem +in a different way. Here is how I did it: + +- If it is the first time when I have to broadcast a message I make an + inquiry scan and save all the devices' addresses to a vector. + +- After the inquiry scan ends I take the first address from the list + and I try to connect to it. If it fails, I try to connect to the next + one. If it succeeds, I save the socket to a list and send the message + to the device. + +- When I have to broadcast another message, first I search on the list + for a new device which I'm not connected to. If there is no new + device on the list I go to the beginning of the list and send the + message to the old devices. After 5 cycles I make a new inquiry scan + to check out if there are new discoverable devices and save them to + the list. If there are no new discoverable devices I reset the + cycling counter and go again through the old list and send messages + to the devices saved in it. + +**Therefore**: + +- every time when I have a broadcast message I look up on the list for + a new device and send the message to it + +- if I reached the end of the list for 5 times and I'm connected to all + the devices from the list I make a new inquiry scan. *The number of + the list's cycles after an inquiry scan could be increased by + redefining the MAX_LOOPS variable* + +- when there are no new devices I send messages to the old ones. + +Doing so, the broadcast control messages will reach the devices but with +delay. + +*NOTICE:* When I have to send a message to a certain device first I +check on the broadcast list to see if we are connected to that device. +If not we try to connect to it and in case of success we save the +address and the socket on the list. If we are already connected to that +device we simply use the socket. + +.. _Pending-features: + +Pending features +^^^^^^^^^^^^^^^^ + +- Implement a testcase for the helper : *The testcase consists of a + program which emulates the plugin and uses the helper. It will + simulate connections, disconnections and data transfers.* + +If you have a new idea about a feature of the plugin or suggestions +about how I could improve the implementation you are welcome to comment +or to contact me. + +.. _WLAN-plugin: + +WLAN plugin +----------- + +This section documents how the wlan transport plugin works. Parts which +are not implemented yet or could be better implemented are described at +the end. + +.. [Transport2014] https://bib.gnunet.org/date.html#paper_5fshort2014 diff --git a/man_developers/subsystems/vpnstack.rst b/man_developers/subsystems/vpnstack.rst @@ -0,0 +1,6 @@ + +VPN and VPN Support +=================== + +.. toctree:: + diff --git a/man_developers/util/index.rst b/man_developers/util/index.rst @@ -0,0 +1,49 @@ + +libgnunetutil +============= + +.. This section of the docs is particularly amenable to + integration with the doxygen output, as it is a library and not + an individual program. + +libgnunetutil is the fundamental library that all GNUnet code builds upon. +Ideally, this library should contain most of the platform dependent code +(except for user interfaces and really special needs that only few +applications have). It is also supposed to offer basic services that most +if not all GNUnet binaries require. The code of libgnunetutil is in the +``src/util/`` directory. The public interface to the library is in the +``gnunet_util.h`` header. + +The functions provided by libgnunetutil fall +roughly into the following categories (in roughly the order of importance +for new developers): + + +* logging (common_logging.c) +* memory allocation (common_allocation.c) +* endianness conversion (common_endian.c) +* internationalization (common_gettext.c) +* String manipulation (string.c) +* file access (disk.c) +* buffered disk IO (bio.c) +* time manipulation (time.c) +* configuration parsing (configuration.c) +* command-line handling (getopt*.c) +* cryptography (crypto_*.c) +* data structures (container_*.c) +* CPS-style scheduling (scheduler.c) +* Program initialization (program.c) +* Networking (network.c, client.c, server*.c, service.c) +* message queuing (mq.c) +* bandwidth calculations (bandwidth.c) +* Other OS-related (os*.c, plugin.c, signal.c) +* Pseudonym management (pseudonym.c) + +It should be noted that only developers that fully understand this entire +API will be able to write good GNUnet code. + +Ideally, porting GNUnet should only require porting the gnunetutil +library. More testcases for the gnunetutil APIs are therefore a great +way to make porting of GNUnet easier. + +.. toctree::