merge of 'bafbafe60ff7360d9948e3e5398c93ae7dd1a576'

and 'f372ddbd62eeb5dd8ec5498076f042c940c6867e'
This commit is contained in:
2010-09-07 01:05:06 +00:00
17 changed files with 2117 additions and 271 deletions

View File

@ -0,0 +1,732 @@
<?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="7cm"
height="7cm"
viewBox="102 159 129 139"
id="svg3091"
version="1.1"
inkscape:version="0.47pre4 r22446"
sodipodi:docname="i2ptunnel_peertopeer.svg"
inkscape:export-filename="/home/mathias/Documents/I2P/i2p.www/www.i2p2/static/images/i2ptunnel_peertopeer.png"
inkscape:export-xdpi="49.999134"
inkscape:export-ydpi="49.999134">
<metadata
id="metadata3257">
<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>
<defs
id="defs3255">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path4394"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 124.01575 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="248.03149 : 124.01575 : 1"
inkscape:persp3d-origin="124.01575 : 82.677165 : 1"
id="perspective3259" />
<inkscape:perspective
id="perspective3524"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3597"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2900"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2900-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3011"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3036"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3036-4"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective5025"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="726"
id="namedview3253"
showgrid="false"
inkscape:zoom="0.95149207"
inkscape:cx="-64.635323"
inkscape:cy="179.6227"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg3091" />
<g
id="g3093"
transform="translate(-124.27542,48.29661)">
<path
style="fill:#b7b79d"
d="m 170.897,186.814 39.968,0 0,7.386 -39.968,0 0,-7.386 z"
id="path3095" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 170.897,186.814 39.968,0 0,7.386 -39.968,0 0,-7.386"
id="path3097" />
<path
style="fill:#c9c9b6"
d="m 170.897,186.814 4.238,-4.018 39.968,0 -4.238,4.018 -39.968,0 z"
id="path3099" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 170.897,186.814 4.238,-4.018 39.968,0 -4.238,4.018 -39.968,0"
id="path3101" />
<path
style="fill:none;stroke:#000000;stroke-width:2.11999989"
d="m 208.63,190.176 -9.591,0"
id="path3103" />
<path
style="fill:#7a7a5a"
d="m 210.865,194.2 4.238,-4.25 0,-7.154 -4.238,4.018 0,7.386 z"
id="path3105" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 210.865,194.2 4.238,-4.25 0,-7.154 -4.238,4.018 0,7.386"
id="path3107" />
<path
style="fill:#c9c9b6"
d="m 171.123,198.885 4.459,-5.585 30.819,0 -4.459,5.585 -30.819,0 z"
id="path3109" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 171.123,198.885 4.459,-5.585 30.819,0 -4.459,5.585 -30.819,0"
id="path3111" />
<path
style="fill:#7a7a5a"
d="m 201.942,200 4.459,-4.685 0,-2.015 -4.459,5.585 0,1.115 z"
id="path3113" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 201.942,200 4.459,-4.685 0,-2.015 -4.459,5.585 0,1.115"
id="path3115" />
<path
style="fill:#b7b79d"
d="m 171.123,198.885 30.819,0 0,1.115 -30.819,0 0,-1.115 z"
id="path3117" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 171.123,198.885 30.819,0 0,1.115 -30.819,0 0,-1.115"
id="path3119" />
<path
style="fill:#000000"
d="m 176.923,185.926 3.357,-3.13 28.35,0 -3.117,3.13 -28.59,0 z"
id="path3121" />
<path
style="fill:none;stroke:#000000;stroke-width:0.02"
d="m 176.923,185.926 3.357,-3.13 28.35,0 -3.117,3.13 -28.59,0"
id="path3123" />
<path
style="fill:#c9c9b6"
d="m 176.696,162.903 3.136,-2.903 28.363,0 -3.136,2.903 -28.363,0 z"
id="path3125" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 176.696,162.903 3.136,-2.903 28.363,0 -3.136,2.903 -28.363,0"
id="path3127" />
<path
style="fill:#b7b79d"
d="m 176.696,162.903 28.59,0 0,22.569 -28.59,0 0,-22.569 z"
id="path3129" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 176.696,162.903 28.577,0 0,22.563 -28.577,0 0,-22.563"
id="path3131" />
<path
style="fill:#ffffff"
d="m 179.152,165.8 23.672,0 0,17.437 -23.672,0 0,-17.437 z"
id="path3133" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 179.152,165.8 23.672,0 0,17.43 -23.672,0 0,-17.43"
id="path3135" />
<path
style="fill:#7a7a5a"
d="m 205.059,185.258 3.136,-3.13 0,-22.128 -3.136,2.903 0,22.355 z"
id="path3137" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 205.059,185.258 3.136,-3.13 0,-22.128 -3.136,2.903 0,22.355"
id="path3139" />
</g>
<g
id="g3219"
transform="translate(134.87712,28.099763)">
<path
style="fill:#b7b79d"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0 z"
id="path3221" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0"
id="path3223" />
<path
style="fill:#c9c9b6"
d="m 139.83,178.978 2.965,-2.978 21.875,0 -2.958,2.978 -21.882,0 z"
id="path3225" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 2.965,-2.978 21.731,0"
id="path3227" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 -21.882,0"
id="path3229" />
<path
style="fill:#c9c9b6"
d="m 141.178,181.132 9.995,0 0,4.857 -9.995,0 0,-4.857 z"
id="path3231" />
<path
style="fill:none;stroke:#626248;stroke-width:0.02"
d="m 141.178,181.132 9.989,0 0,4.85 -9.989,0 0,-4.85"
id="path3233" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 142.527,183.567 7.01,0"
id="path3235" />
<path
style="fill:#7a7a5a"
d="m 161.712,216 2.958,-2.985 0,-37.015 -2.958,2.978 0,37.022 z"
id="path3237" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 161.712,216 2.814,-2.834"
id="path3239" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 0,37.022"
id="path3241" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 140.105,213.559 21.6,0"
id="path3243" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 140.105,193.837 21.6,0"
id="path3245" />
<path
style="fill:none;stroke:#494936;stroke-width:0.60000002"
d="m 139.83,213.29 21.855,0"
id="path3247" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 139.83,193.562 21.855,0"
id="path3249" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.02"
d="m 141.178,185.727 0,-4.595 9.72,0"
id="path3251" />
</g>
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="52.2197"
y="266.53781"
id="text3232"><tspan
sodipodi:role="line"
id="tspan3234"
x="52.2197"
y="266.53781"
style="font-size:11.20825386px">Client</tspan></text>
<text
xml:space="preserve"
style="font-size:16.81238174px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="268.38885"
y="267.14429"
id="text3236"><tspan
sodipodi:role="line"
id="tspan3238"
x="268.38885"
y="267.14429"
style="font-size:11.20825386px">Peers</tspan></text>
<g
transform="matrix(0.75311128,0,0,0.75311128,66.977055,17.740053)"
id="g3183">
<path
style="fill:#0078aa"
d="m 171.824,286.241 -0.049,-0.589 -0.13,-0.599 -0.22,-0.589 -0.309,-0.579 -0.4,-0.589 -0.479,-0.579 -0.569,-0.559 -0.639,-0.549 -0.738,-0.539 -0.809,-0.519 -0.888,-0.52 -0.969,-0.499 -1.038,-0.479 -1.108,-0.469 -1.178,-0.439 -1.228,-0.42 -1.297,-0.399 -1.368,-0.369 -1.408,-0.37 -1.457,-0.309 -1.507,-0.309 -1.558,-0.27 -1.587,-0.26 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.139 -1.717,-0.11 -1.737,-0.08 -1.747,-0.03 -1.767,-0.03 0,0 -1.747,0.03 -1.737,0.03 -1.737,0.08 -1.717,0.11 -1.707,0.139 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.26 -1.558,0.27 -1.517,0.309 -1.447,0.309 -1.408,0.37 -1.368,0.369 -1.297,0.399 -1.228,0.42 -1.178,0.439 -1.108,0.469 -1.038,0.479 -0.979,0.499 -0.878,0.52 -0.819,0.519 -0.728,0.539 -0.639,0.549 -0.569,0.559 -0.479,0.579 -0.4,0.589 -0.309,0.579 -0.23,0.589 -0.12,0.599 -0.049,0.589 0,0 0.049,0.609 0.12,0.588 0.23,0.589 0.309,0.589 0.4,0.579 0.479,0.579 0.569,0.559 0.639,0.549 0.728,0.54 0.819,0.529 0.878,0.499 0.979,0.519 1.038,0.479 1.108,0.459 1.178,0.429 1.228,0.43 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.329 1.517,0.3 1.558,0.269 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.17 1.707,0.119 1.717,0.11 1.737,0.08 1.737,0.05 1.747,0.01 0,0 1.767,-0.01 1.747,-0.05 1.737,-0.08 1.717,-0.11 1.707,-0.119 1.697,-0.17 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.269 1.507,-0.3 1.457,-0.329 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.43 1.178,-0.429 1.108,-0.459 1.038,-0.479 0.969,-0.519 0.888,-0.499 0.809,-0.529 0.738,-0.54 0.639,-0.549 0.569,-0.559 0.479,-0.579 0.4,-0.579 0.309,-0.589 0.22,-0.589 0.13,-0.588 0.049,-0.609 z"
id="path3185" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,286.061 -0.05,-0.599 -0.129,-0.569 -0.22,-0.589 -0.3,-0.569 -0.399,-0.579 -0.489,-0.559 -0.539,-0.549 -0.659,-0.549 -0.729,-0.529 -0.808,-0.529 -0.879,-0.489 -0.968,-0.49 -1.018,-0.489 -1.098,-0.449 -1.178,-0.439 -1.238,-0.399 -1.288,-0.4 -1.347,-0.369 -1.388,-0.34 -1.467,-0.329 -1.508,-0.289 -1.527,-0.27 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.16 -1.687,-0.139 -1.707,-0.08 -1.737,-0.09 -1.737,-0.05 -1.747,0 0,0 -1.737,0 -1.747,0.05 -1.727,0.09 -1.707,0.08 -1.697,0.139 -1.677,0.16 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.27 -1.518,0.289 -1.447,0.329 -1.388,0.34 -1.357,0.369 -1.308,0.4 -1.238,0.399 -1.158,0.439 -1.108,0.449 -1.028,0.489 -0.949,0.49 -0.868,0.489 -0.819,0.529 -0.738,0.529 -0.639,0.549 -0.559,0.549 -0.499,0.559 -0.37,0.579 -0.319,0.569 -0.22,0.589 -0.12,0.569 -0.049,0.599 0,0 0.049,0.589 0.12,0.579 0.22,0.579 0.319,0.569 0.37,0.579 0.499,0.559 0.559,0.549 0.639,0.529 0.738,0.549 0.819,0.529 0.868,0.499 0.949,0.479 1.028,0.48 1.108,0.459 1.158,0.429 1.238,0.409 1.308,0.38 1.357,0.389 1.388,0.339 1.447,0.32 1.518,0.309 1.527,0.26 1.577,0.239 1.627,0.23 1.647,0.18 1.677,0.149 1.697,0.15 1.707,0.09 1.727,0.08 1.747,0.04 1.737,0.02 0,0 1.747,-0.02 1.737,-0.04 1.737,-0.08 1.707,-0.09 1.687,-0.15 1.687,-0.149 1.647,-0.18 1.618,-0.23 1.587,-0.239 1.527,-0.26 1.508,-0.309 1.467,-0.32 1.388,-0.339 1.347,-0.389 1.288,-0.38 1.238,-0.409 1.178,-0.429 1.098,-0.459 1.018,-0.48 0.968,-0.479 0.879,-0.499 0.808,-0.529 0.729,-0.549 0.659,-0.529 0.539,-0.549 0.489,-0.559 0.399,-0.579 0.3,-0.569 0.22,-0.579 0.129,-0.579 0.05,-0.589"
id="path3187" />
<path
style="fill:#0078aa"
d="m 102.676,269.969 0,16.491 68.749,0 0,-16.491 -68.749,0 z"
id="path3189" />
<path
style="fill:#00b4ff"
d="m 171.824,269.739 -0.049,-0.579 -0.13,-0.598 -0.22,-0.589 -0.309,-0.589 -0.4,-0.589 -0.479,-0.569 -0.569,-0.559 -0.639,-0.559 -0.738,-0.53 -0.809,-0.529 -0.888,-0.509 -0.969,-0.519 -1.038,-0.469 -1.108,-0.469 -1.178,-0.439 -1.228,-0.41 -1.297,-0.399 -1.368,-0.379 -1.408,-0.35 -1.457,-0.329 -1.507,-0.31 -1.558,-0.259 -1.587,-0.27 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.119 -1.717,-0.11 -1.737,-0.08 -1.747,-0.06 -1.767,0 0,0 -1.747,0 -1.737,0.06 -1.737,0.08 -1.717,0.11 -1.707,0.119 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.27 -1.558,0.259 -1.517,0.31 -1.447,0.329 -1.408,0.35 -1.368,0.379 -1.297,0.399 -1.228,0.41 -1.178,0.439 -1.108,0.469 -1.038,0.469 -0.979,0.519 -0.878,0.509 -0.819,0.529 -0.728,0.53 -0.639,0.559 -0.569,0.559 -0.479,0.569 -0.4,0.589 -0.309,0.589 -0.23,0.589 -0.12,0.598 -0.049,0.579 0,0 0.049,0.609 0.12,0.599 0.23,0.589 0.309,0.579 0.4,0.589 0.479,0.559 0.569,0.579 0.639,0.549 0.728,0.539 0.819,0.529 0.878,0.51 0.979,0.509 1.038,0.479 1.108,0.439 1.178,0.459 1.228,0.42 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.319 1.517,0.309 1.558,0.27 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.16 1.707,0.119 1.717,0.11 1.737,0.09 1.737,0.05 1.747,0 0,0 1.767,0 1.747,-0.05 1.737,-0.09 1.717,-0.11 1.707,-0.119 1.697,-0.16 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.27 1.507,-0.309 1.457,-0.319 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.42 1.178,-0.459 1.108,-0.439 1.038,-0.479 0.969,-0.509 0.888,-0.51 0.809,-0.529 0.738,-0.539 0.639,-0.549 0.569,-0.579 0.479,-0.559 0.4,-0.589 0.309,-0.579 0.22,-0.589 0.13,-0.599 0.049,-0.609 z"
id="path3191" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 -0.05,-0.599 -0.129,-0.589 -0.22,-0.559 -0.3,-0.589 -0.399,-0.569 -0.489,-0.559 -0.539,-0.539 -0.659,-0.559 -0.729,-0.519 -0.808,-0.539 -0.879,-0.5 -0.968,-0.499 -1.018,-0.469 -1.098,-0.439 -1.178,-0.459 -1.238,-0.4 -1.288,-0.389 -1.347,-0.369 -1.388,-0.34 -1.467,-0.339 -1.508,-0.29 -1.527,-0.269 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.14 -1.687,-0.139 -1.707,-0.1 -1.737,-0.09 -1.737,-0.04 -1.747,-0.02 0,0 -1.737,0.02 -1.747,0.04 -1.727,0.09 -1.707,0.1 -1.697,0.139 -1.677,0.14 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.269 -1.518,0.29 -1.447,0.339 -1.388,0.34 -1.357,0.369 -1.308,0.389 -1.238,0.4 -1.158,0.459 -1.108,0.439 -1.028,0.469 -0.949,0.499 -0.868,0.5 -0.819,0.539 -0.738,0.519 -0.639,0.559 -0.559,0.539 -0.499,0.559 -0.37,0.569 -0.319,0.589 -0.22,0.559 -0.12,0.589 -0.049,0.599 0,0 0.049,0.579 0.12,0.589 0.22,0.559 0.319,0.579 0.37,0.579 0.499,0.559 0.559,0.559 0.639,0.549 0.738,0.529 0.819,0.519 0.868,0.509 0.949,0.469 1.028,0.489 1.108,0.45 1.158,0.439 1.238,0.409 1.308,0.389 1.357,0.37 1.388,0.339 1.447,0.33 1.518,0.309 1.527,0.25 1.577,0.259 1.627,0.21 1.647,0.189 1.677,0.17 1.697,0.14 1.707,0.08 1.727,0.08 1.747,0.05 1.737,0.01 0,0 1.747,-0.01 1.737,-0.05 1.737,-0.08 1.707,-0.08 1.687,-0.14 1.687,-0.17 1.647,-0.189 1.618,-0.21 1.587,-0.259 1.527,-0.25 1.508,-0.309 1.467,-0.33 1.388,-0.339 1.347,-0.37 1.288,-0.389 1.238,-0.409 1.178,-0.439 1.098,-0.45 1.018,-0.489 0.968,-0.469 0.879,-0.509 0.808,-0.519 0.729,-0.529 0.659,-0.549 0.539,-0.559 0.489,-0.559 0.399,-0.579 0.3,-0.579 0.22,-0.559 0.129,-0.589 0.05,-0.579"
id="path3193" />
<path
style="fill:#000000"
d="m 137.874,267.074 5.041,1.657 12.169,-4.961 5.44,1.657 -2.955,-4.123 -14.225,0 5.85,1.248 -11.32,4.522 z"
id="path3195" />
<path
style="fill:#000000"
d="m 135.768,271.626 -5.002,-1.657 -11.749,4.961 -5.86,-1.667 2.935,4.542 14.674,0 -6.299,-1.657 11.301,-4.522 z"
id="path3197" />
<path
style="fill:#000000"
d="m 114.405,262.552 5.031,-1.657 12.149,4.532 5.46,-1.228 -2.925,4.113 -14.265,0 5.86,-1.238 -11.31,-4.522 z"
id="path3199" />
<path
style="fill:#000000"
d="m 159.676,276.568 -5.021,1.647 -11.74,-4.952 -5.87,1.667 2.935,-4.132 14.675,0 -6.299,1.217 11.32,4.553 z"
id="path3201" />
<path
style="fill:#ffffff"
d="m 138.293,267.483 5.051,1.648 12.149,-4.932 5.451,1.657 -2.935,-4.142 -14.265,0 5.879,1.237 -11.33,4.532 z"
id="path3203" />
<path
style="fill:#ffffff"
d="m 136.217,272.015 -5.051,-1.637 -11.73,4.952 -5.87,-1.657 2.935,4.542 14.665,0 -6.269,-1.647 11.32,-4.553 z"
id="path3205" />
<path
style="fill:#ffffff"
d="m 114.834,262.951 5.021,-1.647 12.159,4.552 5.451,-1.258 -2.935,4.133 -14.255,0 5.879,-1.248 -11.32,-4.532 z"
id="path3207" />
<path
style="fill:#ffffff"
d="m 160.105,276.977 -5.021,1.657 -11.74,-4.961 -5.879,1.657 2.925,-4.113 14.694,0 -6.289,1.228 11.31,4.532 z"
id="path3209" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 102.676,269.57 0,16.471"
id="path3211" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 0,16.471"
id="path3213" />
<path
style="fill:#000000"
d="m 124.467,283.995 7.547,0 4.612,3.713 4.602,-3.713 7.128,0 0,-1.648 5.041,2.456 -5.041,2.486 0,-1.647 -6.279,0 -4.203,2.885 4.203,3.284 6.279,0 0,-2.037 5.041,2.875 -5.041,2.486 0,-1.667 -7.128,0 -4.602,-3.694 -4.612,3.694 -7.547,0 0,1.667 -5.031,-2.486 5.031,-2.875 0,2.037 6.699,0 4.202,-2.875 -4.202,-3.294 -6.699,0 0,1.647 -5.031,-2.486 5.031,-2.456 0,1.648 z"
id="path3215" />
<path
style="fill:#ffffff"
d="m 124.897,284.394 7.536,0 4.612,3.703 4.602,-3.703 7.148,0 0,-1.647 5.011,2.485 -5.011,2.476 0,-1.647 -6.299,0 -4.203,2.875 4.203,3.294 6.299,0 0,-2.056 5.011,2.885 -5.011,2.475 0,-1.657 -7.148,0 -4.602,-3.703 -4.612,3.703 -7.536,0 0,1.657 -5.042,-2.475 5.042,-2.885 0,2.056 6.688,0 4.183,-2.885 -4.183,-3.284 -6.688,0 0,1.647 -5.042,-2.476 5.042,-2.485 0,1.647 z"
id="path3217" />
</g>
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="143.47925"
y="266.56204"
id="text3232-1"><tspan
sodipodi:role="line"
id="tspan3234-7"
x="143.47925"
y="266.56204"
style="font-size:11.20825386px">I2PTunnel</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m -23.12158,114.55692 106.149072,0"
id="path3614"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 176.56479,114.55692 140.83144,0"
id="path4836"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<g
id="g3219-0"
transform="translate(134.85585,-107.12416)">
<path
style="fill:#b7b79d"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0 z"
id="path3221-3" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0"
id="path3223-4" />
<path
style="fill:#c9c9b6"
d="m 139.83,178.978 2.965,-2.978 21.875,0 -2.958,2.978 -21.882,0 z"
id="path3225-0" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 2.965,-2.978 21.731,0"
id="path3227-3" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 -21.882,0"
id="path3229-9" />
<path
style="fill:#c9c9b6"
d="m 141.178,181.132 9.995,0 0,4.857 -9.995,0 0,-4.857 z"
id="path3231-1" />
<path
style="fill:none;stroke:#626248;stroke-width:0.02"
d="m 141.178,181.132 9.989,0 0,4.85 -9.989,0 0,-4.85"
id="path3233-9" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 142.527,183.567 7.01,0"
id="path3235-6" />
<path
style="fill:#7a7a5a"
d="m 161.712,216 2.958,-2.985 0,-37.015 -2.958,2.978 0,37.022 z"
id="path3237-9" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 161.712,216 2.814,-2.834"
id="path3239-3" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 0,37.022"
id="path3241-3" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 140.105,213.559 21.6,0"
id="path3243-8" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 140.105,193.837 21.6,0"
id="path3245-0" />
<path
style="fill:none;stroke:#494936;stroke-width:0.60000002"
d="m 139.83,213.29 21.855,0"
id="path3247-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 139.83,193.562 21.855,0"
id="path3249-6" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.02"
d="m 141.178,185.727 0,-4.595 9.72,0"
id="path3251-6" />
</g>
<g
id="g3219-6"
transform="translate(134.38113,-56.133163)">
<path
style="fill:#b7b79d"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0 z"
id="path3221-9" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0"
id="path3223-8" />
<path
style="fill:#c9c9b6"
d="m 139.83,178.978 2.965,-2.978 21.875,0 -2.958,2.978 -21.882,0 z"
id="path3225-7" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 2.965,-2.978 21.731,0"
id="path3227-2" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 -21.882,0"
id="path3229-8" />
<path
style="fill:#c9c9b6"
d="m 141.178,181.132 9.995,0 0,4.857 -9.995,0 0,-4.857 z"
id="path3231-2" />
<path
style="fill:none;stroke:#626248;stroke-width:0.02"
d="m 141.178,181.132 9.989,0 0,4.85 -9.989,0 0,-4.85"
id="path3233-99" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 142.527,183.567 7.01,0"
id="path3235-60" />
<path
style="fill:#7a7a5a"
d="m 161.712,216 2.958,-2.985 0,-37.015 -2.958,2.978 0,37.022 z"
id="path3237-2" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 161.712,216 2.814,-2.834"
id="path3239-7" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 0,37.022"
id="path3241-6" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 140.105,213.559 21.6,0"
id="path3243-1" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 140.105,193.837 21.6,0"
id="path3245-3" />
<path
style="fill:none;stroke:#494936;stroke-width:0.60000002"
d="m 139.83,213.29 21.855,0"
id="path3247-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 139.83,193.562 21.855,0"
id="path3249-1" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.02"
d="m 141.178,185.727 0,-4.595 9.72,0"
id="path3251-5" />
</g>
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="280.74731"
y="181.24799"
id="text3232-2"><tspan
sodipodi:role="line"
id="tspan3234-0"
x="280.74731"
y="181.24799"
style="font-size:11.20825386px">...</tspan></text>
<g
transform="matrix(0.75311128,0,0,0.75311128,66.155046,-65.60384)"
id="g3183-0">
<path
style="fill:#0078aa"
d="m 171.824,286.241 -0.049,-0.589 -0.13,-0.599 -0.22,-0.589 -0.309,-0.579 -0.4,-0.589 -0.479,-0.579 -0.569,-0.559 -0.639,-0.549 -0.738,-0.539 -0.809,-0.519 -0.888,-0.52 -0.969,-0.499 -1.038,-0.479 -1.108,-0.469 -1.178,-0.439 -1.228,-0.42 -1.297,-0.399 -1.368,-0.369 -1.408,-0.37 -1.457,-0.309 -1.507,-0.309 -1.558,-0.27 -1.587,-0.26 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.139 -1.717,-0.11 -1.737,-0.08 -1.747,-0.03 -1.767,-0.03 0,0 -1.747,0.03 -1.737,0.03 -1.737,0.08 -1.717,0.11 -1.707,0.139 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.26 -1.558,0.27 -1.517,0.309 -1.447,0.309 -1.408,0.37 -1.368,0.369 -1.297,0.399 -1.228,0.42 -1.178,0.439 -1.108,0.469 -1.038,0.479 -0.979,0.499 -0.878,0.52 -0.819,0.519 -0.728,0.539 -0.639,0.549 -0.569,0.559 -0.479,0.579 -0.4,0.589 -0.309,0.579 -0.23,0.589 -0.12,0.599 -0.049,0.589 0,0 0.049,0.609 0.12,0.588 0.23,0.589 0.309,0.589 0.4,0.579 0.479,0.579 0.569,0.559 0.639,0.549 0.728,0.54 0.819,0.529 0.878,0.499 0.979,0.519 1.038,0.479 1.108,0.459 1.178,0.429 1.228,0.43 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.329 1.517,0.3 1.558,0.269 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.17 1.707,0.119 1.717,0.11 1.737,0.08 1.737,0.05 1.747,0.01 0,0 1.767,-0.01 1.747,-0.05 1.737,-0.08 1.717,-0.11 1.707,-0.119 1.697,-0.17 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.269 1.507,-0.3 1.457,-0.329 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.43 1.178,-0.429 1.108,-0.459 1.038,-0.479 0.969,-0.519 0.888,-0.499 0.809,-0.529 0.738,-0.54 0.639,-0.549 0.569,-0.559 0.479,-0.579 0.4,-0.579 0.309,-0.589 0.22,-0.589 0.13,-0.588 0.049,-0.609 z"
id="path3185-2" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,286.061 -0.05,-0.599 -0.129,-0.569 -0.22,-0.589 -0.3,-0.569 -0.399,-0.579 -0.489,-0.559 -0.539,-0.549 -0.659,-0.549 -0.729,-0.529 -0.808,-0.529 -0.879,-0.489 -0.968,-0.49 -1.018,-0.489 -1.098,-0.449 -1.178,-0.439 -1.238,-0.399 -1.288,-0.4 -1.347,-0.369 -1.388,-0.34 -1.467,-0.329 -1.508,-0.289 -1.527,-0.27 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.16 -1.687,-0.139 -1.707,-0.08 -1.737,-0.09 -1.737,-0.05 -1.747,0 0,0 -1.737,0 -1.747,0.05 -1.727,0.09 -1.707,0.08 -1.697,0.139 -1.677,0.16 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.27 -1.518,0.289 -1.447,0.329 -1.388,0.34 -1.357,0.369 -1.308,0.4 -1.238,0.399 -1.158,0.439 -1.108,0.449 -1.028,0.489 -0.949,0.49 -0.868,0.489 -0.819,0.529 -0.738,0.529 -0.639,0.549 -0.559,0.549 -0.499,0.559 -0.37,0.579 -0.319,0.569 -0.22,0.589 -0.12,0.569 -0.049,0.599 0,0 0.049,0.589 0.12,0.579 0.22,0.579 0.319,0.569 0.37,0.579 0.499,0.559 0.559,0.549 0.639,0.529 0.738,0.549 0.819,0.529 0.868,0.499 0.949,0.479 1.028,0.48 1.108,0.459 1.158,0.429 1.238,0.409 1.308,0.38 1.357,0.389 1.388,0.339 1.447,0.32 1.518,0.309 1.527,0.26 1.577,0.239 1.627,0.23 1.647,0.18 1.677,0.149 1.697,0.15 1.707,0.09 1.727,0.08 1.747,0.04 1.737,0.02 0,0 1.747,-0.02 1.737,-0.04 1.737,-0.08 1.707,-0.09 1.687,-0.15 1.687,-0.149 1.647,-0.18 1.618,-0.23 1.587,-0.239 1.527,-0.26 1.508,-0.309 1.467,-0.32 1.388,-0.339 1.347,-0.389 1.288,-0.38 1.238,-0.409 1.178,-0.429 1.098,-0.459 1.018,-0.48 0.968,-0.479 0.879,-0.499 0.808,-0.529 0.729,-0.549 0.659,-0.529 0.539,-0.549 0.489,-0.559 0.399,-0.579 0.3,-0.569 0.22,-0.579 0.129,-0.579 0.05,-0.589"
id="path3187-9" />
<path
style="fill:#0078aa"
d="m 102.676,269.969 0,16.491 68.749,0 0,-16.491 -68.749,0 z"
id="path3189-4" />
<path
style="fill:#00b4ff"
d="m 171.824,269.739 -0.049,-0.579 -0.13,-0.598 -0.22,-0.589 -0.309,-0.589 -0.4,-0.589 -0.479,-0.569 -0.569,-0.559 -0.639,-0.559 -0.738,-0.53 -0.809,-0.529 -0.888,-0.509 -0.969,-0.519 -1.038,-0.469 -1.108,-0.469 -1.178,-0.439 -1.228,-0.41 -1.297,-0.399 -1.368,-0.379 -1.408,-0.35 -1.457,-0.329 -1.507,-0.31 -1.558,-0.259 -1.587,-0.27 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.119 -1.717,-0.11 -1.737,-0.08 -1.747,-0.06 -1.767,0 0,0 -1.747,0 -1.737,0.06 -1.737,0.08 -1.717,0.11 -1.707,0.119 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.27 -1.558,0.259 -1.517,0.31 -1.447,0.329 -1.408,0.35 -1.368,0.379 -1.297,0.399 -1.228,0.41 -1.178,0.439 -1.108,0.469 -1.038,0.469 -0.979,0.519 -0.878,0.509 -0.819,0.529 -0.728,0.53 -0.639,0.559 -0.569,0.559 -0.479,0.569 -0.4,0.589 -0.309,0.589 -0.23,0.589 -0.12,0.598 -0.049,0.579 0,0 0.049,0.609 0.12,0.599 0.23,0.589 0.309,0.579 0.4,0.589 0.479,0.559 0.569,0.579 0.639,0.549 0.728,0.539 0.819,0.529 0.878,0.51 0.979,0.509 1.038,0.479 1.108,0.439 1.178,0.459 1.228,0.42 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.319 1.517,0.309 1.558,0.27 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.16 1.707,0.119 1.717,0.11 1.737,0.09 1.737,0.05 1.747,0 0,0 1.767,0 1.747,-0.05 1.737,-0.09 1.717,-0.11 1.707,-0.119 1.697,-0.16 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.27 1.507,-0.309 1.457,-0.319 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.42 1.178,-0.459 1.108,-0.439 1.038,-0.479 0.969,-0.509 0.888,-0.51 0.809,-0.529 0.738,-0.539 0.639,-0.549 0.569,-0.579 0.479,-0.559 0.4,-0.589 0.309,-0.579 0.22,-0.589 0.13,-0.599 0.049,-0.609 z"
id="path3191-3" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 -0.05,-0.599 -0.129,-0.589 -0.22,-0.559 -0.3,-0.589 -0.399,-0.569 -0.489,-0.559 -0.539,-0.539 -0.659,-0.559 -0.729,-0.519 -0.808,-0.539 -0.879,-0.5 -0.968,-0.499 -1.018,-0.469 -1.098,-0.439 -1.178,-0.459 -1.238,-0.4 -1.288,-0.389 -1.347,-0.369 -1.388,-0.34 -1.467,-0.339 -1.508,-0.29 -1.527,-0.269 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.14 -1.687,-0.139 -1.707,-0.1 -1.737,-0.09 -1.737,-0.04 -1.747,-0.02 0,0 -1.737,0.02 -1.747,0.04 -1.727,0.09 -1.707,0.1 -1.697,0.139 -1.677,0.14 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.269 -1.518,0.29 -1.447,0.339 -1.388,0.34 -1.357,0.369 -1.308,0.389 -1.238,0.4 -1.158,0.459 -1.108,0.439 -1.028,0.469 -0.949,0.499 -0.868,0.5 -0.819,0.539 -0.738,0.519 -0.639,0.559 -0.559,0.539 -0.499,0.559 -0.37,0.569 -0.319,0.589 -0.22,0.559 -0.12,0.589 -0.049,0.599 0,0 0.049,0.579 0.12,0.589 0.22,0.559 0.319,0.579 0.37,0.579 0.499,0.559 0.559,0.559 0.639,0.549 0.738,0.529 0.819,0.519 0.868,0.509 0.949,0.469 1.028,0.489 1.108,0.45 1.158,0.439 1.238,0.409 1.308,0.389 1.357,0.37 1.388,0.339 1.447,0.33 1.518,0.309 1.527,0.25 1.577,0.259 1.627,0.21 1.647,0.189 1.677,0.17 1.697,0.14 1.707,0.08 1.727,0.08 1.747,0.05 1.737,0.01 0,0 1.747,-0.01 1.737,-0.05 1.737,-0.08 1.707,-0.08 1.687,-0.14 1.687,-0.17 1.647,-0.189 1.618,-0.21 1.587,-0.259 1.527,-0.25 1.508,-0.309 1.467,-0.33 1.388,-0.339 1.347,-0.37 1.288,-0.389 1.238,-0.409 1.178,-0.439 1.098,-0.45 1.018,-0.489 0.968,-0.469 0.879,-0.509 0.808,-0.519 0.729,-0.529 0.659,-0.549 0.539,-0.559 0.489,-0.559 0.399,-0.579 0.3,-0.579 0.22,-0.559 0.129,-0.589 0.05,-0.579"
id="path3193-5" />
<path
style="fill:#000000"
d="m 137.874,267.074 5.041,1.657 12.169,-4.961 5.44,1.657 -2.955,-4.123 -14.225,0 5.85,1.248 -11.32,4.522 z"
id="path3195-1" />
<path
style="fill:#000000"
d="m 135.768,271.626 -5.002,-1.657 -11.749,4.961 -5.86,-1.667 2.935,4.542 14.674,0 -6.299,-1.657 11.301,-4.522 z"
id="path3197-7" />
<path
style="fill:#000000"
d="m 114.405,262.552 5.031,-1.657 12.149,4.532 5.46,-1.228 -2.925,4.113 -14.265,0 5.86,-1.238 -11.31,-4.522 z"
id="path3199-4" />
<path
style="fill:#000000"
d="m 159.676,276.568 -5.021,1.647 -11.74,-4.952 -5.87,1.667 2.935,-4.132 14.675,0 -6.299,1.217 11.32,4.553 z"
id="path3201-3" />
<path
style="fill:#ffffff"
d="m 138.293,267.483 5.051,1.648 12.149,-4.932 5.451,1.657 -2.935,-4.142 -14.265,0 5.879,1.237 -11.33,4.532 z"
id="path3203-1" />
<path
style="fill:#ffffff"
d="m 136.217,272.015 -5.051,-1.637 -11.73,4.952 -5.87,-1.657 2.935,4.542 14.665,0 -6.269,-1.647 11.32,-4.553 z"
id="path3205-4" />
<path
style="fill:#ffffff"
d="m 114.834,262.951 5.021,-1.647 12.159,4.552 5.451,-1.258 -2.935,4.133 -14.255,0 5.879,-1.248 -11.32,-4.532 z"
id="path3207-6" />
<path
style="fill:#ffffff"
d="m 160.105,276.977 -5.021,1.657 -11.74,-4.961 -5.879,1.657 2.925,-4.113 14.694,0 -6.289,1.228 11.31,4.532 z"
id="path3209-9" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 102.676,269.57 0,16.471"
id="path3211-4" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 0,16.471"
id="path3213-2" />
<path
style="fill:#000000"
d="m 124.467,283.995 7.547,0 4.612,3.713 4.602,-3.713 7.128,0 0,-1.648 5.041,2.456 -5.041,2.486 0,-1.647 -6.279,0 -4.203,2.885 4.203,3.284 6.279,0 0,-2.037 5.041,2.875 -5.041,2.486 0,-1.667 -7.128,0 -4.602,-3.694 -4.612,3.694 -7.547,0 0,1.667 -5.031,-2.486 5.031,-2.875 0,2.037 6.699,0 4.202,-2.875 -4.202,-3.294 -6.699,0 0,1.647 -5.031,-2.486 5.031,-2.456 0,1.648 z"
id="path3215-2" />
<path
style="fill:#ffffff"
d="m 124.897,284.394 7.536,0 4.612,3.703 4.602,-3.703 7.148,0 0,-1.647 5.011,2.485 -5.011,2.476 0,-1.647 -6.299,0 -4.203,2.875 4.203,3.294 6.299,0 0,-2.056 5.011,2.885 -5.011,2.475 0,-1.657 -7.148,0 -4.602,-3.703 -4.612,3.703 -7.536,0 0,1.657 -5.042,-2.475 5.042,-2.885 0,2.056 6.688,0 4.183,-2.885 -4.183,-3.284 -6.688,0 0,1.647 -5.042,-2.476 5.042,-2.485 0,1.647 z"
id="path3217-6" />
</g>
<g
transform="matrix(0.75311128,0,0,0.75311128,66.040764,-121.3287)"
id="g3183-1">
<path
style="fill:#0078aa"
d="m 171.824,286.241 -0.049,-0.589 -0.13,-0.599 -0.22,-0.589 -0.309,-0.579 -0.4,-0.589 -0.479,-0.579 -0.569,-0.559 -0.639,-0.549 -0.738,-0.539 -0.809,-0.519 -0.888,-0.52 -0.969,-0.499 -1.038,-0.479 -1.108,-0.469 -1.178,-0.439 -1.228,-0.42 -1.297,-0.399 -1.368,-0.369 -1.408,-0.37 -1.457,-0.309 -1.507,-0.309 -1.558,-0.27 -1.587,-0.26 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.139 -1.717,-0.11 -1.737,-0.08 -1.747,-0.03 -1.767,-0.03 0,0 -1.747,0.03 -1.737,0.03 -1.737,0.08 -1.717,0.11 -1.707,0.139 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.26 -1.558,0.27 -1.517,0.309 -1.447,0.309 -1.408,0.37 -1.368,0.369 -1.297,0.399 -1.228,0.42 -1.178,0.439 -1.108,0.469 -1.038,0.479 -0.979,0.499 -0.878,0.52 -0.819,0.519 -0.728,0.539 -0.639,0.549 -0.569,0.559 -0.479,0.579 -0.4,0.589 -0.309,0.579 -0.23,0.589 -0.12,0.599 -0.049,0.589 0,0 0.049,0.609 0.12,0.588 0.23,0.589 0.309,0.589 0.4,0.579 0.479,0.579 0.569,0.559 0.639,0.549 0.728,0.54 0.819,0.529 0.878,0.499 0.979,0.519 1.038,0.479 1.108,0.459 1.178,0.429 1.228,0.43 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.329 1.517,0.3 1.558,0.269 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.17 1.707,0.119 1.717,0.11 1.737,0.08 1.737,0.05 1.747,0.01 0,0 1.767,-0.01 1.747,-0.05 1.737,-0.08 1.717,-0.11 1.707,-0.119 1.697,-0.17 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.269 1.507,-0.3 1.457,-0.329 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.43 1.178,-0.429 1.108,-0.459 1.038,-0.479 0.969,-0.519 0.888,-0.499 0.809,-0.529 0.738,-0.54 0.639,-0.549 0.569,-0.559 0.479,-0.579 0.4,-0.579 0.309,-0.589 0.22,-0.589 0.13,-0.588 0.049,-0.609 z"
id="path3185-28" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,286.061 -0.05,-0.599 -0.129,-0.569 -0.22,-0.589 -0.3,-0.569 -0.399,-0.579 -0.489,-0.559 -0.539,-0.549 -0.659,-0.549 -0.729,-0.529 -0.808,-0.529 -0.879,-0.489 -0.968,-0.49 -1.018,-0.489 -1.098,-0.449 -1.178,-0.439 -1.238,-0.399 -1.288,-0.4 -1.347,-0.369 -1.388,-0.34 -1.467,-0.329 -1.508,-0.289 -1.527,-0.27 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.16 -1.687,-0.139 -1.707,-0.08 -1.737,-0.09 -1.737,-0.05 -1.747,0 0,0 -1.737,0 -1.747,0.05 -1.727,0.09 -1.707,0.08 -1.697,0.139 -1.677,0.16 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.27 -1.518,0.289 -1.447,0.329 -1.388,0.34 -1.357,0.369 -1.308,0.4 -1.238,0.399 -1.158,0.439 -1.108,0.449 -1.028,0.489 -0.949,0.49 -0.868,0.489 -0.819,0.529 -0.738,0.529 -0.639,0.549 -0.559,0.549 -0.499,0.559 -0.37,0.579 -0.319,0.569 -0.22,0.589 -0.12,0.569 -0.049,0.599 0,0 0.049,0.589 0.12,0.579 0.22,0.579 0.319,0.569 0.37,0.579 0.499,0.559 0.559,0.549 0.639,0.529 0.738,0.549 0.819,0.529 0.868,0.499 0.949,0.479 1.028,0.48 1.108,0.459 1.158,0.429 1.238,0.409 1.308,0.38 1.357,0.389 1.388,0.339 1.447,0.32 1.518,0.309 1.527,0.26 1.577,0.239 1.627,0.23 1.647,0.18 1.677,0.149 1.697,0.15 1.707,0.09 1.727,0.08 1.747,0.04 1.737,0.02 0,0 1.747,-0.02 1.737,-0.04 1.737,-0.08 1.707,-0.09 1.687,-0.15 1.687,-0.149 1.647,-0.18 1.618,-0.23 1.587,-0.239 1.527,-0.26 1.508,-0.309 1.467,-0.32 1.388,-0.339 1.347,-0.389 1.288,-0.38 1.238,-0.409 1.178,-0.429 1.098,-0.459 1.018,-0.48 0.968,-0.479 0.879,-0.499 0.808,-0.529 0.729,-0.549 0.659,-0.529 0.539,-0.549 0.489,-0.559 0.399,-0.579 0.3,-0.569 0.22,-0.579 0.129,-0.579 0.05,-0.589"
id="path3187-8" />
<path
style="fill:#0078aa"
d="m 102.676,269.969 0,16.491 68.749,0 0,-16.491 -68.749,0 z"
id="path3189-9" />
<path
style="fill:#00b4ff"
d="m 171.824,269.739 -0.049,-0.579 -0.13,-0.598 -0.22,-0.589 -0.309,-0.589 -0.4,-0.589 -0.479,-0.569 -0.569,-0.559 -0.639,-0.559 -0.738,-0.53 -0.809,-0.529 -0.888,-0.509 -0.969,-0.519 -1.038,-0.469 -1.108,-0.469 -1.178,-0.439 -1.228,-0.41 -1.297,-0.399 -1.368,-0.379 -1.408,-0.35 -1.457,-0.329 -1.507,-0.31 -1.558,-0.259 -1.587,-0.27 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.119 -1.717,-0.11 -1.737,-0.08 -1.747,-0.06 -1.767,0 0,0 -1.747,0 -1.737,0.06 -1.737,0.08 -1.717,0.11 -1.707,0.119 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.27 -1.558,0.259 -1.517,0.31 -1.447,0.329 -1.408,0.35 -1.368,0.379 -1.297,0.399 -1.228,0.41 -1.178,0.439 -1.108,0.469 -1.038,0.469 -0.979,0.519 -0.878,0.509 -0.819,0.529 -0.728,0.53 -0.639,0.559 -0.569,0.559 -0.479,0.569 -0.4,0.589 -0.309,0.589 -0.23,0.589 -0.12,0.598 -0.049,0.579 0,0 0.049,0.609 0.12,0.599 0.23,0.589 0.309,0.579 0.4,0.589 0.479,0.559 0.569,0.579 0.639,0.549 0.728,0.539 0.819,0.529 0.878,0.51 0.979,0.509 1.038,0.479 1.108,0.439 1.178,0.459 1.228,0.42 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.319 1.517,0.309 1.558,0.27 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.16 1.707,0.119 1.717,0.11 1.737,0.09 1.737,0.05 1.747,0 0,0 1.767,0 1.747,-0.05 1.737,-0.09 1.717,-0.11 1.707,-0.119 1.697,-0.16 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.27 1.507,-0.309 1.457,-0.319 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.42 1.178,-0.459 1.108,-0.439 1.038,-0.479 0.969,-0.509 0.888,-0.51 0.809,-0.529 0.738,-0.539 0.639,-0.549 0.569,-0.579 0.479,-0.559 0.4,-0.589 0.309,-0.579 0.22,-0.589 0.13,-0.599 0.049,-0.609 z"
id="path3191-2" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 -0.05,-0.599 -0.129,-0.589 -0.22,-0.559 -0.3,-0.589 -0.399,-0.569 -0.489,-0.559 -0.539,-0.539 -0.659,-0.559 -0.729,-0.519 -0.808,-0.539 -0.879,-0.5 -0.968,-0.499 -1.018,-0.469 -1.098,-0.439 -1.178,-0.459 -1.238,-0.4 -1.288,-0.389 -1.347,-0.369 -1.388,-0.34 -1.467,-0.339 -1.508,-0.29 -1.527,-0.269 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.14 -1.687,-0.139 -1.707,-0.1 -1.737,-0.09 -1.737,-0.04 -1.747,-0.02 0,0 -1.737,0.02 -1.747,0.04 -1.727,0.09 -1.707,0.1 -1.697,0.139 -1.677,0.14 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.269 -1.518,0.29 -1.447,0.339 -1.388,0.34 -1.357,0.369 -1.308,0.389 -1.238,0.4 -1.158,0.459 -1.108,0.439 -1.028,0.469 -0.949,0.499 -0.868,0.5 -0.819,0.539 -0.738,0.519 -0.639,0.559 -0.559,0.539 -0.499,0.559 -0.37,0.569 -0.319,0.589 -0.22,0.559 -0.12,0.589 -0.049,0.599 0,0 0.049,0.579 0.12,0.589 0.22,0.559 0.319,0.579 0.37,0.579 0.499,0.559 0.559,0.559 0.639,0.549 0.738,0.529 0.819,0.519 0.868,0.509 0.949,0.469 1.028,0.489 1.108,0.45 1.158,0.439 1.238,0.409 1.308,0.389 1.357,0.37 1.388,0.339 1.447,0.33 1.518,0.309 1.527,0.25 1.577,0.259 1.627,0.21 1.647,0.189 1.677,0.17 1.697,0.14 1.707,0.08 1.727,0.08 1.747,0.05 1.737,0.01 0,0 1.747,-0.01 1.737,-0.05 1.737,-0.08 1.707,-0.08 1.687,-0.14 1.687,-0.17 1.647,-0.189 1.618,-0.21 1.587,-0.259 1.527,-0.25 1.508,-0.309 1.467,-0.33 1.388,-0.339 1.347,-0.37 1.288,-0.389 1.238,-0.409 1.178,-0.439 1.098,-0.45 1.018,-0.489 0.968,-0.469 0.879,-0.509 0.808,-0.519 0.729,-0.529 0.659,-0.549 0.539,-0.559 0.489,-0.559 0.399,-0.579 0.3,-0.579 0.22,-0.559 0.129,-0.589 0.05,-0.579"
id="path3193-8" />
<path
style="fill:#000000"
d="m 137.874,267.074 5.041,1.657 12.169,-4.961 5.44,1.657 -2.955,-4.123 -14.225,0 5.85,1.248 -11.32,4.522 z"
id="path3195-8" />
<path
style="fill:#000000"
d="m 135.768,271.626 -5.002,-1.657 -11.749,4.961 -5.86,-1.667 2.935,4.542 14.674,0 -6.299,-1.657 11.301,-4.522 z"
id="path3197-8" />
<path
style="fill:#000000"
d="m 114.405,262.552 5.031,-1.657 12.149,4.532 5.46,-1.228 -2.925,4.113 -14.265,0 5.86,-1.238 -11.31,-4.522 z"
id="path3199-6" />
<path
style="fill:#000000"
d="m 159.676,276.568 -5.021,1.647 -11.74,-4.952 -5.87,1.667 2.935,-4.132 14.675,0 -6.299,1.217 11.32,4.553 z"
id="path3201-8" />
<path
style="fill:#ffffff"
d="m 138.293,267.483 5.051,1.648 12.149,-4.932 5.451,1.657 -2.935,-4.142 -14.265,0 5.879,1.237 -11.33,4.532 z"
id="path3203-3" />
<path
style="fill:#ffffff"
d="m 136.217,272.015 -5.051,-1.637 -11.73,4.952 -5.87,-1.657 2.935,4.542 14.665,0 -6.269,-1.647 11.32,-4.553 z"
id="path3205-8" />
<path
style="fill:#ffffff"
d="m 114.834,262.951 5.021,-1.647 12.159,4.552 5.451,-1.258 -2.935,4.133 -14.255,0 5.879,-1.248 -11.32,-4.532 z"
id="path3207-3" />
<path
style="fill:#ffffff"
d="m 160.105,276.977 -5.021,1.657 -11.74,-4.961 -5.879,1.657 2.925,-4.113 14.694,0 -6.289,1.228 11.31,4.532 z"
id="path3209-3" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 102.676,269.57 0,16.471"
id="path3211-3" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 0,16.471"
id="path3213-8" />
<path
style="fill:#000000"
d="m 124.467,283.995 7.547,0 4.612,3.713 4.602,-3.713 7.128,0 0,-1.648 5.041,2.456 -5.041,2.486 0,-1.647 -6.279,0 -4.203,2.885 4.203,3.284 6.279,0 0,-2.037 5.041,2.875 -5.041,2.486 0,-1.667 -7.128,0 -4.602,-3.694 -4.612,3.694 -7.547,0 0,1.667 -5.031,-2.486 5.031,-2.875 0,2.037 6.699,0 4.202,-2.875 -4.202,-3.294 -6.699,0 0,1.647 -5.031,-2.486 5.031,-2.456 0,1.648 z"
id="path3215-0" />
<path
style="fill:#ffffff"
d="m 124.897,284.394 7.536,0 4.612,3.703 4.602,-3.703 7.148,0 0,-1.647 5.011,2.485 -5.011,2.476 0,-1.647 -6.299,0 -4.203,2.875 4.203,3.294 6.299,0 0,-2.056 5.011,2.885 -5.011,2.475 0,-1.657 -7.148,0 -4.602,-3.703 -4.612,3.703 -7.536,0 0,1.657 -5.042,-2.475 5.042,-2.885 0,2.056 6.688,0 4.183,-2.885 -4.183,-3.284 -6.688,0 0,1.647 -5.042,-2.476 5.042,-2.485 0,1.647 z"
id="path3217-4" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="M -24.172561,102.99613 83.027492,-13.662752"
id="path3144"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="M -35.733351,87.231415 81.976511,-112.45496"
id="path3146"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 175.51381,-125.06673 139.78046,0"
id="path3148"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 173.41185,-27.325504 141.88242,0"
id="path3150"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="165.27502"
y="181.54456"
id="text3232-2-6"><tspan
sodipodi:role="line"
id="tspan3234-0-7"
x="165.27502"
y="181.54456"
style="font-size:11.20825386px">...</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,368 @@
<?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="7cm"
height="7cm"
viewBox="102 159 129 139"
id="svg3091"
version="1.1"
inkscape:version="0.47pre4 r22446"
sodipodi:docname="i2ptunnel_serverclient.svg"
inkscape:export-filename="/home/mathias/Documents/I2P/i2p.www/www.i2p2/static/images/i2ptunnel_serverclient.png"
inkscape:export-xdpi="49.999134"
inkscape:export-ydpi="49.999134">
<metadata
id="metadata3257">
<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>
<defs
id="defs3255">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path4394"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 124.01575 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="248.03149 : 124.01575 : 1"
inkscape:persp3d-origin="124.01575 : 82.677165 : 1"
id="perspective3259" />
<inkscape:perspective
id="perspective3524"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3597"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="726"
id="namedview3253"
showgrid="false"
inkscape:zoom="0.95149207"
inkscape:cx="124.01575"
inkscape:cy="124.01575"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg3091" />
<g
id="g3093"
transform="translate(-124.27542,48.29661)">
<path
style="fill:#b7b79d"
d="m 170.897,186.814 39.968,0 0,7.386 -39.968,0 0,-7.386 z"
id="path3095" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 170.897,186.814 39.968,0 0,7.386 -39.968,0 0,-7.386"
id="path3097" />
<path
style="fill:#c9c9b6"
d="m 170.897,186.814 4.238,-4.018 39.968,0 -4.238,4.018 -39.968,0 z"
id="path3099" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 170.897,186.814 4.238,-4.018 39.968,0 -4.238,4.018 -39.968,0"
id="path3101" />
<path
style="fill:none;stroke:#000000;stroke-width:2.11999989"
d="m 208.63,190.176 -9.591,0"
id="path3103" />
<path
style="fill:#7a7a5a"
d="m 210.865,194.2 4.238,-4.25 0,-7.154 -4.238,4.018 0,7.386 z"
id="path3105" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 210.865,194.2 4.238,-4.25 0,-7.154 -4.238,4.018 0,7.386"
id="path3107" />
<path
style="fill:#c9c9b6"
d="m 171.123,198.885 4.459,-5.585 30.819,0 -4.459,5.585 -30.819,0 z"
id="path3109" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 171.123,198.885 4.459,-5.585 30.819,0 -4.459,5.585 -30.819,0"
id="path3111" />
<path
style="fill:#7a7a5a"
d="m 201.942,200 4.459,-4.685 0,-2.015 -4.459,5.585 0,1.115 z"
id="path3113" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 201.942,200 4.459,-4.685 0,-2.015 -4.459,5.585 0,1.115"
id="path3115" />
<path
style="fill:#b7b79d"
d="m 171.123,198.885 30.819,0 0,1.115 -30.819,0 0,-1.115 z"
id="path3117" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 171.123,198.885 30.819,0 0,1.115 -30.819,0 0,-1.115"
id="path3119" />
<path
style="fill:#000000"
d="m 176.923,185.926 3.357,-3.13 28.35,0 -3.117,3.13 -28.59,0 z"
id="path3121" />
<path
style="fill:none;stroke:#000000;stroke-width:0.02"
d="m 176.923,185.926 3.357,-3.13 28.35,0 -3.117,3.13 -28.59,0"
id="path3123" />
<path
style="fill:#c9c9b6"
d="m 176.696,162.903 3.136,-2.903 28.363,0 -3.136,2.903 -28.363,0 z"
id="path3125" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 176.696,162.903 3.136,-2.903 28.363,0 -3.136,2.903 -28.363,0"
id="path3127" />
<path
style="fill:#b7b79d"
d="m 176.696,162.903 28.59,0 0,22.569 -28.59,0 0,-22.569 z"
id="path3129" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 176.696,162.903 28.577,0 0,22.563 -28.577,0 0,-22.563"
id="path3131" />
<path
style="fill:#ffffff"
d="m 179.152,165.8 23.672,0 0,17.437 -23.672,0 0,-17.437 z"
id="path3133" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 179.152,165.8 23.672,0 0,17.43 -23.672,0 0,-17.43"
id="path3135" />
<path
style="fill:#7a7a5a"
d="m 205.059,185.258 3.136,-3.13 0,-22.128 -3.136,2.903 0,22.355 z"
id="path3137" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 205.059,185.258 3.136,-3.13 0,-22.128 -3.136,2.903 0,22.355"
id="path3139" />
</g>
<g
id="g3219"
transform="translate(134.87712,28.099763)">
<path
style="fill:#b7b79d"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0 z"
id="path3221" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 0,37.022 21.882,0 0,-37.022 -21.882,0"
id="path3223" />
<path
style="fill:#c9c9b6"
d="m 139.83,178.978 2.965,-2.978 21.875,0 -2.958,2.978 -21.882,0 z"
id="path3225" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 139.83,178.978 2.965,-2.978 21.731,0"
id="path3227" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 -21.882,0"
id="path3229" />
<path
style="fill:#c9c9b6"
d="m 141.178,181.132 9.995,0 0,4.857 -9.995,0 0,-4.857 z"
id="path3231" />
<path
style="fill:none;stroke:#626248;stroke-width:0.02"
d="m 141.178,181.132 9.989,0 0,4.85 -9.989,0 0,-4.85"
id="path3233" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 142.527,183.567 7.01,0"
id="path3235" />
<path
style="fill:#7a7a5a"
d="m 161.712,216 2.958,-2.985 0,-37.015 -2.958,2.978 0,37.022 z"
id="path3237" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 161.712,216 2.814,-2.834"
id="path3239" />
<path
style="fill:none;stroke:#494936;stroke-width:0.02"
d="m 164.526,176.151 -2.814,2.827 0,37.022"
id="path3241" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.60000002"
d="m 140.105,213.559 21.6,0"
id="path3243" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 140.105,193.837 21.6,0"
id="path3245" />
<path
style="fill:none;stroke:#494936;stroke-width:0.60000002"
d="m 139.83,213.29 21.855,0"
id="path3247" />
<path
style="fill:none;stroke:#000000;stroke-width:0.60000002"
d="m 139.83,193.562 21.855,0"
id="path3249" />
<path
style="fill:none;stroke:#ecece7;stroke-width:0.02"
d="m 141.178,185.727 0,-4.595 9.72,0"
id="path3251" />
</g>
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="52.2197"
y="266.53781"
id="text3232"><tspan
sodipodi:role="line"
id="tspan3234"
x="52.2197"
y="266.53781"
style="font-size:11.20825386px">Client</tspan></text>
<text
xml:space="preserve"
style="font-size:16.81238174px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="268.38885"
y="267.14429"
id="text3236"><tspan
sodipodi:role="line"
id="tspan3238"
x="268.38885"
y="267.14429"
style="font-size:11.20825386px">Server</tspan></text>
<g
transform="matrix(0.75311128,0,0,0.75311128,66.977055,17.740053)"
id="g3183">
<path
style="fill:#0078aa"
d="m 171.824,286.241 -0.049,-0.589 -0.13,-0.599 -0.22,-0.589 -0.309,-0.579 -0.4,-0.589 -0.479,-0.579 -0.569,-0.559 -0.639,-0.549 -0.738,-0.539 -0.809,-0.519 -0.888,-0.52 -0.969,-0.499 -1.038,-0.479 -1.108,-0.469 -1.178,-0.439 -1.228,-0.42 -1.297,-0.399 -1.368,-0.369 -1.408,-0.37 -1.457,-0.309 -1.507,-0.309 -1.558,-0.27 -1.587,-0.26 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.139 -1.717,-0.11 -1.737,-0.08 -1.747,-0.03 -1.767,-0.03 0,0 -1.747,0.03 -1.737,0.03 -1.737,0.08 -1.717,0.11 -1.707,0.139 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.26 -1.558,0.27 -1.517,0.309 -1.447,0.309 -1.408,0.37 -1.368,0.369 -1.297,0.399 -1.228,0.42 -1.178,0.439 -1.108,0.469 -1.038,0.479 -0.979,0.499 -0.878,0.52 -0.819,0.519 -0.728,0.539 -0.639,0.549 -0.569,0.559 -0.479,0.579 -0.4,0.589 -0.309,0.579 -0.23,0.589 -0.12,0.599 -0.049,0.589 0,0 0.049,0.609 0.12,0.588 0.23,0.589 0.309,0.589 0.4,0.579 0.479,0.579 0.569,0.559 0.639,0.549 0.728,0.54 0.819,0.529 0.878,0.499 0.979,0.519 1.038,0.479 1.108,0.459 1.178,0.429 1.228,0.43 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.329 1.517,0.3 1.558,0.269 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.17 1.707,0.119 1.717,0.11 1.737,0.08 1.737,0.05 1.747,0.01 0,0 1.767,-0.01 1.747,-0.05 1.737,-0.08 1.717,-0.11 1.707,-0.119 1.697,-0.17 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.269 1.507,-0.3 1.457,-0.329 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.43 1.178,-0.429 1.108,-0.459 1.038,-0.479 0.969,-0.519 0.888,-0.499 0.809,-0.529 0.738,-0.54 0.639,-0.549 0.569,-0.559 0.479,-0.579 0.4,-0.579 0.309,-0.589 0.22,-0.589 0.13,-0.588 0.049,-0.609 z"
id="path3185" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,286.061 -0.05,-0.599 -0.129,-0.569 -0.22,-0.589 -0.3,-0.569 -0.399,-0.579 -0.489,-0.559 -0.539,-0.549 -0.659,-0.549 -0.729,-0.529 -0.808,-0.529 -0.879,-0.489 -0.968,-0.49 -1.018,-0.489 -1.098,-0.449 -1.178,-0.439 -1.238,-0.399 -1.288,-0.4 -1.347,-0.369 -1.388,-0.34 -1.467,-0.329 -1.508,-0.289 -1.527,-0.27 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.16 -1.687,-0.139 -1.707,-0.08 -1.737,-0.09 -1.737,-0.05 -1.747,0 0,0 -1.737,0 -1.747,0.05 -1.727,0.09 -1.707,0.08 -1.697,0.139 -1.677,0.16 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.27 -1.518,0.289 -1.447,0.329 -1.388,0.34 -1.357,0.369 -1.308,0.4 -1.238,0.399 -1.158,0.439 -1.108,0.449 -1.028,0.489 -0.949,0.49 -0.868,0.489 -0.819,0.529 -0.738,0.529 -0.639,0.549 -0.559,0.549 -0.499,0.559 -0.37,0.579 -0.319,0.569 -0.22,0.589 -0.12,0.569 -0.049,0.599 0,0 0.049,0.589 0.12,0.579 0.22,0.579 0.319,0.569 0.37,0.579 0.499,0.559 0.559,0.549 0.639,0.529 0.738,0.549 0.819,0.529 0.868,0.499 0.949,0.479 1.028,0.48 1.108,0.459 1.158,0.429 1.238,0.409 1.308,0.38 1.357,0.389 1.388,0.339 1.447,0.32 1.518,0.309 1.527,0.26 1.577,0.239 1.627,0.23 1.647,0.18 1.677,0.149 1.697,0.15 1.707,0.09 1.727,0.08 1.747,0.04 1.737,0.02 0,0 1.747,-0.02 1.737,-0.04 1.737,-0.08 1.707,-0.09 1.687,-0.15 1.687,-0.149 1.647,-0.18 1.618,-0.23 1.587,-0.239 1.527,-0.26 1.508,-0.309 1.467,-0.32 1.388,-0.339 1.347,-0.389 1.288,-0.38 1.238,-0.409 1.178,-0.429 1.098,-0.459 1.018,-0.48 0.968,-0.479 0.879,-0.499 0.808,-0.529 0.729,-0.549 0.659,-0.529 0.539,-0.549 0.489,-0.559 0.399,-0.579 0.3,-0.569 0.22,-0.579 0.129,-0.579 0.05,-0.589"
id="path3187" />
<path
style="fill:#0078aa"
d="m 102.676,269.969 0,16.491 68.749,0 0,-16.491 -68.749,0 z"
id="path3189" />
<path
style="fill:#00b4ff"
d="m 171.824,269.739 -0.049,-0.579 -0.13,-0.598 -0.22,-0.589 -0.309,-0.589 -0.4,-0.589 -0.479,-0.569 -0.569,-0.559 -0.639,-0.559 -0.738,-0.53 -0.809,-0.529 -0.888,-0.509 -0.969,-0.519 -1.038,-0.469 -1.108,-0.469 -1.178,-0.439 -1.228,-0.41 -1.297,-0.399 -1.368,-0.379 -1.408,-0.35 -1.457,-0.329 -1.507,-0.31 -1.558,-0.259 -1.587,-0.27 -1.637,-0.219 -1.647,-0.19 -1.697,-0.16 -1.707,-0.119 -1.717,-0.11 -1.737,-0.08 -1.747,-0.06 -1.767,0 0,0 -1.747,0 -1.737,0.06 -1.737,0.08 -1.717,0.11 -1.707,0.119 -1.697,0.16 -1.647,0.19 -1.637,0.219 -1.587,0.27 -1.558,0.259 -1.517,0.31 -1.447,0.329 -1.408,0.35 -1.368,0.379 -1.297,0.399 -1.228,0.41 -1.178,0.439 -1.108,0.469 -1.038,0.469 -0.979,0.519 -0.878,0.509 -0.819,0.529 -0.728,0.53 -0.639,0.559 -0.569,0.559 -0.479,0.569 -0.4,0.589 -0.309,0.589 -0.23,0.589 -0.12,0.598 -0.049,0.579 0,0 0.049,0.609 0.12,0.599 0.23,0.589 0.309,0.579 0.4,0.589 0.479,0.559 0.569,0.579 0.639,0.549 0.728,0.539 0.819,0.529 0.878,0.51 0.979,0.509 1.038,0.479 1.108,0.439 1.178,0.459 1.228,0.42 1.297,0.399 1.368,0.379 1.408,0.35 1.447,0.319 1.517,0.309 1.558,0.27 1.587,0.26 1.637,0.219 1.647,0.19 1.697,0.16 1.707,0.119 1.717,0.11 1.737,0.09 1.737,0.05 1.747,0 0,0 1.767,0 1.747,-0.05 1.737,-0.09 1.717,-0.11 1.707,-0.119 1.697,-0.16 1.647,-0.19 1.637,-0.219 1.587,-0.26 1.558,-0.27 1.507,-0.309 1.457,-0.319 1.408,-0.35 1.368,-0.379 1.297,-0.399 1.228,-0.42 1.178,-0.459 1.108,-0.439 1.038,-0.479 0.969,-0.509 0.888,-0.51 0.809,-0.529 0.738,-0.539 0.639,-0.549 0.569,-0.579 0.479,-0.559 0.4,-0.589 0.309,-0.579 0.22,-0.589 0.13,-0.599 0.049,-0.609 z"
id="path3191" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 -0.05,-0.599 -0.129,-0.589 -0.22,-0.559 -0.3,-0.589 -0.399,-0.569 -0.489,-0.559 -0.539,-0.539 -0.659,-0.559 -0.729,-0.519 -0.808,-0.539 -0.879,-0.5 -0.968,-0.499 -1.018,-0.469 -1.098,-0.439 -1.178,-0.459 -1.238,-0.4 -1.288,-0.389 -1.347,-0.369 -1.388,-0.34 -1.467,-0.339 -1.508,-0.29 -1.527,-0.269 -1.587,-0.25 -1.618,-0.219 -1.647,-0.19 -1.687,-0.14 -1.687,-0.139 -1.707,-0.1 -1.737,-0.09 -1.737,-0.04 -1.747,-0.02 0,0 -1.737,0.02 -1.747,0.04 -1.727,0.09 -1.707,0.1 -1.697,0.139 -1.677,0.14 -1.647,0.19 -1.627,0.219 -1.577,0.25 -1.527,0.269 -1.518,0.29 -1.447,0.339 -1.388,0.34 -1.357,0.369 -1.308,0.389 -1.238,0.4 -1.158,0.459 -1.108,0.439 -1.028,0.469 -0.949,0.499 -0.868,0.5 -0.819,0.539 -0.738,0.519 -0.639,0.559 -0.559,0.539 -0.499,0.559 -0.37,0.569 -0.319,0.589 -0.22,0.559 -0.12,0.589 -0.049,0.599 0,0 0.049,0.579 0.12,0.589 0.22,0.559 0.319,0.579 0.37,0.579 0.499,0.559 0.559,0.559 0.639,0.549 0.738,0.529 0.819,0.519 0.868,0.509 0.949,0.469 1.028,0.489 1.108,0.45 1.158,0.439 1.238,0.409 1.308,0.389 1.357,0.37 1.388,0.339 1.447,0.33 1.518,0.309 1.527,0.25 1.577,0.259 1.627,0.21 1.647,0.189 1.677,0.17 1.697,0.14 1.707,0.08 1.727,0.08 1.747,0.05 1.737,0.01 0,0 1.747,-0.01 1.737,-0.05 1.737,-0.08 1.707,-0.08 1.687,-0.14 1.687,-0.17 1.647,-0.189 1.618,-0.21 1.587,-0.259 1.527,-0.25 1.508,-0.309 1.467,-0.33 1.388,-0.339 1.347,-0.37 1.288,-0.389 1.238,-0.409 1.178,-0.439 1.098,-0.45 1.018,-0.489 0.968,-0.469 0.879,-0.509 0.808,-0.519 0.729,-0.529 0.659,-0.549 0.539,-0.559 0.489,-0.559 0.399,-0.579 0.3,-0.579 0.22,-0.559 0.129,-0.589 0.05,-0.579"
id="path3193" />
<path
style="fill:#000000"
d="m 137.874,267.074 5.041,1.657 12.169,-4.961 5.44,1.657 -2.955,-4.123 -14.225,0 5.85,1.248 -11.32,4.522 z"
id="path3195" />
<path
style="fill:#000000"
d="m 135.768,271.626 -5.002,-1.657 -11.749,4.961 -5.86,-1.667 2.935,4.542 14.674,0 -6.299,-1.657 11.301,-4.522 z"
id="path3197" />
<path
style="fill:#000000"
d="m 114.405,262.552 5.031,-1.657 12.149,4.532 5.46,-1.228 -2.925,4.113 -14.265,0 5.86,-1.238 -11.31,-4.522 z"
id="path3199" />
<path
style="fill:#000000"
d="m 159.676,276.568 -5.021,1.647 -11.74,-4.952 -5.87,1.667 2.935,-4.132 14.675,0 -6.299,1.217 11.32,4.553 z"
id="path3201" />
<path
style="fill:#ffffff"
d="m 138.293,267.483 5.051,1.648 12.149,-4.932 5.451,1.657 -2.935,-4.142 -14.265,0 5.879,1.237 -11.33,4.532 z"
id="path3203" />
<path
style="fill:#ffffff"
d="m 136.217,272.015 -5.051,-1.637 -11.73,4.952 -5.87,-1.657 2.935,4.542 14.665,0 -6.269,-1.647 11.32,-4.553 z"
id="path3205" />
<path
style="fill:#ffffff"
d="m 114.834,262.951 5.021,-1.647 12.159,4.552 5.451,-1.258 -2.935,4.133 -14.255,0 5.879,-1.248 -11.32,-4.532 z"
id="path3207" />
<path
style="fill:#ffffff"
d="m 160.105,276.977 -5.021,1.657 -11.74,-4.961 -5.879,1.657 2.925,-4.113 14.694,0 -6.289,1.228 11.31,4.532 z"
id="path3209" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 102.676,269.57 0,16.471"
id="path3211" />
<path
style="fill:none;stroke:#aae6ff;stroke-width:0.02"
d="m 171.425,269.57 0,16.471"
id="path3213" />
<path
style="fill:#000000"
d="m 124.467,283.995 7.547,0 4.612,3.713 4.602,-3.713 7.128,0 0,-1.648 5.041,2.456 -5.041,2.486 0,-1.647 -6.279,0 -4.203,2.885 4.203,3.284 6.279,0 0,-2.037 5.041,2.875 -5.041,2.486 0,-1.667 -7.128,0 -4.602,-3.694 -4.612,3.694 -7.547,0 0,1.667 -5.031,-2.486 5.031,-2.875 0,2.037 6.699,0 4.202,-2.875 -4.202,-3.294 -6.699,0 0,1.647 -5.031,-2.486 5.031,-2.456 0,1.648 z"
id="path3215" />
<path
style="fill:#ffffff"
d="m 124.897,284.394 7.536,0 4.612,3.703 4.602,-3.703 7.148,0 0,-1.647 5.011,2.485 -5.011,2.476 0,-1.647 -6.299,0 -4.203,2.875 4.203,3.294 6.299,0 0,-2.056 5.011,2.885 -5.011,2.475 0,-1.657 -7.148,0 -4.602,-3.703 -4.612,3.703 -7.536,0 0,1.657 -5.042,-2.475 5.042,-2.885 0,2.056 6.688,0 4.183,-2.885 -4.183,-3.284 -6.688,0 0,1.647 -5.042,-2.476 5.042,-2.485 0,1.647 z"
id="path3217" />
</g>
<text
xml:space="preserve"
style="font-size:6.16453981px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="143.47925"
y="266.56204"
id="text3232-1"><tspan
sodipodi:role="line"
id="tspan3234-7"
x="143.47925"
y="266.56204"
style="font-size:11.20825386px">I2PTunnel</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m -23.12158,114.55692 106.149072,0"
id="path3614"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
d="m 176.56479,114.55692 140.83144,0"
id="path4836"
transform="matrix(0.5604127,0,0,0.5604127,97,159)" />
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -108,7 +108,7 @@
<br /><b>Documentation</b><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="how.html">Hoe werkt het?</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="techintro.html">Tech intro</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="applications.html">Applicaties</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="applications.html">Apps ontwikkelen</a><br />
<br /><b>Development</b><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="api.html">API</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="licenses.html">Licenties</a><br />
@ -310,7 +310,7 @@
<br /><b>Documentation</b><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="how.html">How does it work?</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="techintro.html">Tech intro</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="applications.html">Applications</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="applications.html">App Dev</a><br />
<br /><b>Development</b><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="api.html">API</a><br />
<img src="/_static/images/sqbullet.png" />&nbsp;<a href="licenses.html">Licenses</a><br />

View File

@ -3,78 +3,93 @@
{% block content %}
<h1>Application Development Guide</h1>
<h2>Why write I2P specific code?</h2>
<h2>Contents</h2>
<ul>
<li><a href="#why">Why write I2P-specific code?</a></li>
<li><a href="#concepts">Important concepts</a></li>
<li><a href="#options">Development options</a></li>
<li><a href="#start"><b>Start developing - a simple guide</b></a></li>
</ul>
<p>Using mihi's <a href="i2ptunnel">I2PTunnel</a> application, you can hook up
application instances and have them talk to each other over standard TCP
sockets. In plain client-server scenarios, this is an effective technique for
many simple protocols, but for distributed systems where each peer may contact
a number of other peers (instead of just a single server), or for systems that
expose TCP or IP information within the communication protocols themselves,
there are problems.</p>
<h2 id="why">Why write I2P-specific code?</h2>
<p>With I2PTunnel, you need to explicitly instantiate an I2PTunnel for each peer
you want to contact - if you are building a distributed instant messenger
application, that means you need to have each peer create an I2PTunnel 'client'
pointing at each peer it wants to contact, plus a single I2PTunnel 'server' to
receive other peer's connections. This process can of course be automated, but
there are nontrivial overheads involved in running more than just a few I2PTunnel
instances. In addition, with many protocols you will need to force everyone to
use the same set of ports for all peers - e.g. if you want to reliably run DCC
chat, everyone needs to agree that port 10001 is Alice, port 10002 is Bob, port
10003 is Charlie, and so on, since the protocol includes TCP/IP specific information
(host and port).</p>
<p>Applications that are designed to work with I2P can take advantage of its
built in data security and optional pseudonymous authentication. All data sent
over the network is transparently end to end encrypted (not even the routers
get the cleartext), and any application using the streaming or datagram
functionality has all of that data authenticated by the sending destination's
public key. As an aside, environments where anonymity instead of pseudonymity
is required are trivially accommodated by either using the I2CP directly, SAM RAW
sessions, or by simply creating a new sending destination whenever needed).</p>
<p>Another important thing to remember is that I2P is simply a communication
system - what data is sent and what is done with that data is outside of its scope.
Applications that are used on top of I2P should be carefully sanitized of any
insecure or identifying data or protocols (hostnames, port numbers, time zone,
character set, etc). This in and of itself is often a daunting task, as
analyzing the safety of a system that has had anonymity and security strapped on to
it is no small feat, giving significant incentive to learn from the experiences of
the traditional application base, but design the application and its communication
protocols with I2P's anonymity and security in mind.</p>
<p>There are also efficiency considerations to review when determining how to
interact on top of I2P. The streaming library and things built on top of it
operate with handshakes similar to TCP, while the core I2P protocols (I2NP and I2CP)
are strictly message based (like UDP or in some instances raw IP). The important
distinction is that with I2P, communication is operating over a long fat network -
each end to end message will have nontrivial latencies, but may contain payloads
of up to 32KB. An application that needs a simple request and response can get rid
of any state and drop the latency incurred by the startup and teardown handshakes
by using (best effort) datagrams without having to worry about MTU detection or
fragmentation of messages under 32KB.
<p>
There are multiple ways to use applications in I2P.
Using <a href="/i2ptunnel.html">I2PTunnel</a>,
you can use regular applications without needing to program explicit I2P support.
This is very effective for client-server scenario's,
where you need to connect to a single website.
You can simply create a tunnel using I2PTunnel to connect to that website, as shown in <a href="#tunnel.serverclient">Figure 1</a>.
</p>
<p>
If your application is distributed, it will require connections to a large amount of peers.
Using I2PTunnel, you will need to create a new tunnel for each peer you want to contact,
as shown in <a href="#tunnel.peertopeer">Figure 2</a>.
This process can of course be automated, but running a lot of I2PTunnel instances creates a large amount of overhead.
In addition, with many protocols you will need to force everyone to
use the same set of ports for all peers - e.g. if you want to reliably run DCC
chat, everyone needs to agree that port 10001 is Alice, port 10002 is Bob, port
10003 is Charlie, and so on, since the protocol includes TCP/IP specific information
(host and port).
</p>
<p>
General network applications often send a lot of additional data that could be used to identify users.
Hostnames, port numbers, time zones, character sets, etc. are often sent without informing the user.
As such, designing the network protocol specifically with anonymity in mind
can avoid compromising user identities.
</p>
<p>
There are also efficiency considerations to review when determining how to
interact on top of I2P. The streaming library and things built on top of it
operate with handshakes similar to TCP, while the core I2P protocols (I2NP and I2CP)
are strictly message based (like UDP or in some instances raw IP). The important
distinction is that with I2P, communication is operating over a long fat network -
each end to end message will have nontrivial latencies, but may contain payloads
of up to 32KB. An application that needs a simple request and response can get rid
of any state and drop the latency incurred by the startup and teardown handshakes
by using (best effort) datagrams without having to worry about MTU detection or
fragmentation of messages under 32KB.
</p>
<center>
<div class="box" id="tunnel.serverclient">
<img src="_static/images/i2ptunnel_serverclient.png" alt="Creating a server-client connection using I2PTunnel only requires creating a single tunnel." title="Creating a server-client connection using I2PTunnel only requires creating a single tunnel." />
<br /><br />
Figure 1: Creating a server-client connection using I2PTunnel only requires creating a single tunnel.
</div>
</center><br/>
<center>
<div class="box" id="tunnel.peertopeer">
<img src="_static/images/i2ptunnel_peertopeer.png" alt="Setting up connections for a peer-to-peer applications requires a very large amount of tunnels." title="Setting up connections for a peer-to-peer applications requires a very large amount of tunnels." />
<br /><br />
Figure 2: Setting up connections for a peer-to-peer applications requires a very large amount of tunnels.
</div>
</center><br/>
<p>
In summary, a number of reasons to write I2P-specific code:
<ul>
<li>
Creating a large amount of I2PTunnel instances consumes a non-trivial amount of resources,
which is problematic for distributed applications (a new tunnel is required for each peer).
</li>
<li>
General network protocols often send a lot of additional data that can be used to identify users.
Programming specifically for I2P allows the creation of a network protocol
that does not leak such information, keeping users anonymous and secure.
</li>
<li>
Network protocols designed for use on the regular internet can be inefficient
on I2P, which is a network with a much higher latency.
</li>
</ul>
</p>
<p>
The ministreaming library itself uses a
functional but inefficient scheme for dealing with reliable and in order delivery
by requiring the equivalent of an ACK after each message which must traverse the
network end to end again (though there are plans for improving this with a more
efficient and robust algorithm). With ministreaming, an application
that uses one of the I2P message oriented protocols could in some situations get
substantially better performance.
However with the full streaming library now the standard interface,
it isn't clear if that is still the case.
Applications written in Java and accessible/runnable
using an HTML interface via the standard webapps/app.war
may be considered for inclusion in the i2p distribution.
</p>
<p>
Applications written in Java and accessible/runnable
using an HTML interface via the standard webapps/app.war
may be considered for inclusion in the i2p distribution.
</p>
<h2>Important ideas</h2>
<h2>Important concepts</h2>
<p>There are a few changes that require adjusting to when using I2P:</p>
@ -93,26 +108,30 @@ location of the end point signed as if there were universal deployment of DNSSEC
to another (or with some special software, it can even operate on multiple routers at
once). This is quite different from the TCP or UDP world where a single end point (port)
must stay on a single host.</li>
<li>I2P destinations are ugly and large - behind the scenes, they contain a 2048bit ElGamal
<li>
<p>
I2P destinations are ugly and large - behind the scenes, they contain a 2048bit ElGamal
public key for encryption, a 1024bit DSA public key for signing, and a variable size
certificate (currently this is the null type, but may contain proof of work, blinded
data, or other information to increase the 'cost' of a destination in an effort to fight
Sybil). <p>There are existing ways to refer to these large and ugly destinations by short
certificate, which may contain proof of work or blinded data.
</p>
<p>
There are existing ways to refer to these large and ugly destinations by short
and pretty names (e.g. "irc.duck.i2p"), but at the moment those techniques do not guarantee
globally uniqueness (since they're stored locally at each person's machine as "hosts.txt")
and the current mechanism is not especially scalable nor secure (updates to one host file is
and the current mechanism is not especially scalable nor secure (updates to one host file are
manually managed within Monotone, and as such, anyone with commit rights on the repository can
change the destinations). There may be some secure, human readable, scalable, and globally
unique, naming system some day, but applications shouldn't depend upon it being in place,
since there are those who don't think such a beast is possible.
<a href="naming.html">Further information on the naming system</a> is available.
</p>
</li>
</ul>
<h3>Anonymity and confidentiality</h3>
<p>A useful thing to remember is that I2P has transparent end to end encryption
and authentication for all data passed over the network - if Bob sends Alice's destination,
and authentication for all data passed over the network - if Bob sends to Alice's destination,
only Alice's destination can receive it, and if Bob is using the datagrams or streaming
library, Alice knows for certain that Bob's destination is the one who sent the data. </p>
@ -132,7 +151,7 @@ UDP, applications don't need to worry about MTU detection and can simply fire of
entire request or response, allowing them to transparently operate in I2P as a UDP-like
application without having to write fragmentation, resends, etc.</p>
<h2>Integration techniques</h2>
<h2 id="options">Development options</h2>
<p>There are several means of sending data over I2P, each with their own pros and cons.
The streaming lib is the recommended interface, used by the majority of I2P applications.
@ -141,8 +160,7 @@ The streaming lib is the recommended interface, used by the majority of I2P appl
<h3>Streaming Lib</h3>
<p>
The <a href="streaming.html">full streaming library</a> is now the standard
interface. Ministreaming and SAM are not recommended.
The streaming lib interface is similar to the ministreaming lib interface described below.
interface. It allows programming using TCP-like sockets, as explained in the <a href="#start.streaming">Streaming development guide</a>.
</p>
<h3>SAM, SAM V2, SAM V3</h3>
@ -185,43 +203,280 @@ their own unique I2P destination and their own set of tunnels, keys, etc.</p>
<h3>Ministreaming</h3>
<p><i>Not recommended</i></p>
<p>For applications written in Java, the simplest way to go is to use the libraries that the SAM
bridge and I2PTunnel applications use. The streaming functionality is exposed in the 'ministreaming'
library, which is centered on the
<a href="http://www.i2p.net/javadoc/net/i2p/client/streaming/package-summary.html">I2PSocketManager</a>,
the <a href="http://www.i2p.net/javadoc/net/i2p/client/streaming/I2PSocket.html">I2PSocket</a>, and the
<a href="http://www.i2p.net/javadoc/net/i2p/client/streaming/I2PServerSocket.html">I2PServerSocket</a>.</p>
<p>
It was possible to write I2P applications in Java using the ministreaming library.
However, the Streaming library has superceded this, and provides better functionality.
</p>
<h3>Datagrams</h3>
<p><i>Not recommended</i></p>
<p>For applications that want to use repliable datagrams, they can be built with the
<a href="http://www.i2p.net/javadoc/net/i2p/client/datagram/I2PDatagramMaker.html">I2PDatagramMaker</a>
and parsed on the receiving side by the
<a href="http://www.i2p.net/javadoc/net/i2p/client/datagram/I2PDatagramDissector.html">I2PDatagramDissector</a>.
In turn, these are sent and received through an
<a href="http://www.i2p.net/javadoc/net/i2p/client/I2PSession.html">I2PSession</a>.</p>
<p>Applications that want to use raw datagrams simply send directly through the I2PSession's
<a href="http://www.i2p.net/javadoc/net/i2p/client/I2PSession.html#sendMessage(net.i2p.data.Destination,%20byte[])">sendMessage(...)</a>
method, receiving notification of available messages through the
<a href="http://www.i2p.net/javadoc/net/i2p/client/I2PSessionListener.html">I2PSessionListener</a> and
then fetching those messages by calling
<a href="http://www.i2p.net/javadoc/net/i2p/client/I2PSession.html#receiveMessage(int)">receiveMessage(...)</a>.</p>
The <a href="datagrams">Datagram library</a> allows sending UDP-like packets.
It's possible to use:
<ul>
<li>Repliable datagrams</li>
<li>Raw datagrams</li>
</ul>
<h3>I2CP</h3>
<p><i>Not easy</i></p>
<p><i>Not recommended</i></p>
<p><a href="i2cp">I2CP</a> itself is a language independent protocol, but to implement an I2CP library
in something other than Java there is a significant amount of code to be written (encryption routines,
object marshalling, asynchronous message handling, etc). While someone could write an I2CP library in
C or something else, it would most likely be more useful to use the C SAM library instead.
I2CP also <a href="i2cp">needs documentation</a>.
</p>
<h3>Web Applications</h3>
I2P comes with the Jetty webserver, and configuring to use the Apache server instead is straightforward.
Any standard web app technology should work.
<h2 id="start">Start developing - a simple guide</h2>
Developing using I2P requires a working I2P installation and a development environment of your own choice.
If you are using Java, you can start development with the <a href="#start.streaming">streaming library</a> or datagram library.
Using another programming language, SAM or BOB can be used.
<h3 id="start.streaming">Developing with the streaming library</h3>
<p>
Development using the streaming library requires the following libraries in your classpath:
<ul>
<li>$I2P/lib/streaming.jar: the streaming library itself.</li>
<li>$I2P/lib/mstreaming.jar: the ministreaming library is used as the base for the streaming library.</li>
<li>$I2P/lib/i2p.jar: some standard I2P classes (like the Destination class) are very convenient when developing.</li>
</ul>
</p>
<p>
Network communication requires the usage of I2P network sockets.
To demonstrate this, we will create an application where a client can send text messages to a server,
who will print the messages and send them back to the client. In other words, the server will function as an echo.
</p>
<p>
We will start by initializing the server application. This requires getting an I2PSocketManager
and creating an I2PServerSocket.
In addition, we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination we use.
</p>
<div class="box">
<pre>
package i2p.echoserver;
import net.i2p.client.I2PSession;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
public class Main {
public static void main(String[] args) {
//Initialize application
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
I2PServerSocket serverSocket = manager.getServerSocket();
I2PSession session = manager.getSession();
System.out.println(session.getMyDestination().toBase64()); //Print the base64 string, the regular string would look like garbage.
//The additional main method code comes here...
}
}
</pre>
<br /><br />
<center>Code example 1: initializing the server application.</center>
</div>
<p>
Once we have an I2PServerSocket, we can create I2PSocket instances to accept connections from clients.
In this example, we will create a single I2PSocket instance, that can only handle one client at a time.
A real server would have to be able to handle multiple clients.
To do this, multiple I2PSocket instances would have to be created, each in separate threads.
Once we have created the I2PSocket instance, we read data, print it and send it back to the client.
The bold code is the new code we add.
</p>
<div class="box">
<pre>
package i2p.echoserver;
</pre>
<b><pre>
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.util.I2PThread;
</pre></b>
<pre>
import net.i2p.client.I2PSession;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
public class Main {
public static void main(String[] args) {
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
I2PServerSocket serverSocket = manager.getServerSocket();
I2PSession session = manager.getSession();
System.out.println(session.getMyDestination().toBase64()); //Print the base64 string, the regular string would look like garbage.
</pre>
<b><pre>
//Create socket to handle clients
I2PThread t = new I2PThread(new ClientHandler(serverSocket));
t.setName("clienthandler1");
t.setDaemon(false);
t.start();
}
private static class ClientHandler implements Runnable {
public ClientHandler(I2PServerSocket socket) {
this.socket = socket;
}
public void run() {
while(true) {
try {
I2PSocket sock = this.socket.accept();
if(sock != null) {
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream())); //Receive from clients
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream())); //Send to clients
String line = br.readLine();
if(line != null) {
System.out.println("Received from client: " + line);
bw.write(line);
bw.flush(); //Flush to make sure everything got sent
}
sock.close();
}
} catch (I2PException ex) {
System.out.println("General I2P exception!");
} catch (ConnectException ex) {
System.out.println("Error connecting!");
} catch (SocketTimeoutException ex) {
System.out.println("Timeout!");
} catch (IOException ex) {
System.out.println("General read/write-exception!");
}
}
}
private I2PServerSocket socket;
}
}
</pre></b>
<br /><br />
<center>Code example 2: accepting connections from clients and handling messages.</center>
</div>
<p>
When you run the above server code, it should print something like this (but without the line endings, it should just be
one huge block of characters):
<pre id="start.streaming.destination">
y17s~L3H9q5xuIyyynyWahAuj6Jeg5VC~Klu9YPquQvD4vlgzmxn4yy~5Z0zVvKJiS2Lk
poPIcB3r9EbFYkz1mzzE3RYY~XFyPTaFQY8omDv49nltI2VCQ5cx7gAt~y4LdWqkyk3au
6HdfYSLr45zxzWRGZnTXQay9HPuYcHysZHJP1lY28QsPz36DHr6IZ0vwMENQsnQ5rhq20
jkB3iheYJeuO7MpL~1xrjgKzteirkCNHvXN8PjxNmxe-pj3QgOiow-R9rEYKyPAyGd2pe
qMD-J12CGfB6MlnmH5qPHGdZ13bUuebHiyZ1jqSprWL-SVIPcynAxD2Uu85ynxnx31Fth
nxFMk07vvggBrLM2Sw82pxNjKDbtO8reawe3cyksIXBBkuobOZdyOxp3NT~x6aLOxwkEq
BOF6kbxV7NPRPnivbNekd1E1GUq08ltDPVMO1pKJuGMsFyZC4Q~osZ8nI59ryouXgn97Q
5ZDEO8-Iazx50~yUQTRgLMOTC5hqnAAAA
</pre>
This is the base64-representation of the server Destination. The client will need this string to reach the server.
</p>
<p>
Now, we will create the client application. Again, a number of steps are required for initialization.
Again, we will need to start by getting an I2PSocketManager.
We won't use an I2PSession and an I2PServerSocket this time.
Instead, we will use the server Destination string to start our connection.
We will ask the user for the Destination string, and create an I2PSocket using this string.
Once we have an I2PSocket, we can start sending and receiving data to and from the server.
</p>
<div class="box">
<pre>
package i2p.echoclient;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
public class Main {
public static void main(String[] args) {
I2PSocketManager manager = I2PSocketManagerFactory.createManager();
System.out.println("Please enter a Destination:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String destinationString = null;
try {
destinationString = br.readLine();
} catch (IOException ex) {
System.out.println("Failed to get a Destination string.");
return;
}
Destination destination = null;
try {
destination = new Destination(destinationString);
} catch (DataFormatException ex) {
System.out.println("Destination string incorrectly formatted.");
return;
}
I2PSocket socket = null;
try {
socket = manager.connect(destination);
} catch (I2PException ex) {
System.out.println("General I2P exception occurred!");
} catch (ConnectException ex) {
System.out.println("Failed to connect!");
} catch (NoRouteToHostException ex) {
System.out.println("Couldn't find host!");
} catch (InterruptedIOException ex) {
System.out.println("Sending/receiving was interrupted!");
}
try {
//Write to server
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("Hello I2P!\n");
bw.flush(); //Flush to make sure everything got sent
//Read from server
BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = null;
while ((s = br2.readLine()) != null) {
System.out.println("Received from server: " + s);
}
socket.close();
} catch (IOException ex) {
System.out.println("Error occurred while sending/receiving!");
}
}
}
</pre>
<br /><br />
<center>Code example 3: starting the client and connecting it to the server application.</center>
</div>
<p>
Finally, you can run both the server and the client application.
First, start the server application. It will print a Destination string (like shown <a href="#start.streaming.destination">above</a>).
Next, start the client application. When it requests a Destination string, you can enter the string printed by the server.
The client will then send 'Hello I2P!' (along with a newline) to the server, who will print the message and send it back to the client.
</p>
<p>
Congratulations, you have successfully communicated over I2P!
</p>
<h2>Existing Applications in Development</h2>
Contact us if you would like to help.
<ul>

View File

@ -18,12 +18,25 @@ technique used in <a href="how_elgamalaes">ElGamal/AES+SessionTag</a> (but we're
<p>
ElGamal is used for asymmetric encryption.
ElGamal is used in several places in I2P:
<ul><li>
To encrypt router-to-router <a href="tunnel-alt-creation.html">Tunnel Build Messages</a>
</li><li>
For end-to-end (destination-to-destination) encryption as a part of <a href="how_elgamalaes">ElGamal/AES+SessionTag</a>
</li><li>
For encryption of some <a href="how_networkdatabase.html#delivery">netDb stores and queries sent to floodfill routers</a>
as a part of <a href="how_elgamalaes">ElGamal/AES+SessionTag</a>
(destination-to-router or router-to-router).
</li></ul>
</p>
<p>
We use common primes for 2048 ElGamal encryption and decryption, as given by <a href="http://tools.ietf.org/html/rfc3526">IETF RFC-3526</a>.
We currently only use ElGamal to encrypt the IV and session key in a single block, followed by the
AES encrypted payload using that key and IV. Specifically, the unencrypted ElGamal
block is formatted (in network byte order):
AES encrypted payload using that key and IV.
<p>
The unencrypted ElGamal contains:
</p>
<p>
<PRE>
+----+----+----+----+----+----+----+----+
@ -42,11 +55,46 @@ block is formatted (in network byte order):
<p>
The H(data) is the SHA256 of the data that is encrypted in the ElGamal block,
and is preceded by a random nonzero byte. The data encrypted in the block
can be up to 222 bytes long. See
<a href="http://trac.i2p2.de/browser/core/java/src/net/i2p/crypto/ElGamalEngine.java?rev=85a542c53d910dffbf34cdcefb8a2faeee96adc4">the ElGamal code</a>.
may be up to 222 bytes long.
As the encrypted data may contain a substantial number of zeros if the
cleartext is smaller than 222 bytes, it is recommended that higher layers pad
the cleartext to 222 bytes with random data.
Total length: typically 255 bytes.
</p><p>
The encrypted ElGamal contains:
</p>
<p>
ElGamal is never used on its own in I2P, but instead always as part of
<a href="how_elgamalaes">ElGamal/AES+SessionTag</a>.
<PRE>
+----+----+----+----+----+----+----+----+
| zero padding... | |
+----+----+----+--// ----+ +
| |
+ +
| ElG encrypted part 1 |
~ ~
| |
+ +----+----+----+----+----+----+----+
| | zero padding... | |
+----+----+----+----+--// ----+ +
| |
+ +
| ElG encrypted part 2 |
~ ~
| |
+ +----+----+----+----+----+----+
| +
+----+----+
</PRE>
Each encrypted part is prepended with zeros to a size of exactly 257 bytes.
Total length: 514 bytes.
In typical usage, higher layers pad the cleartext data to 222 bytes,
resulting in an unencrypted block of 255 bytes.
This is encoded as two 256-byte encrypted parts,
and there is a single byte of zero padding before each part at this layer.
</p><p>
See
<a href="http://trac.i2p2.de/browser/core/java/src/net/i2p/crypto/ElGamalEngine.java?rev=85a542c53d910dffbf34cdcefb8a2faeee96adc4">the ElGamal code</a>.
<p>
The shared prime is the
@ -103,8 +151,19 @@ It may be quite difficult to make any change backward-compatible.
<H2><a name="AES">AES</a></H2>
<p>
AES is used for symmetric encryption.
<p>
AES is used for symmetric encryption, in several cases:
<ul><li>
For <a href="#transports">transport encryption</a> after DH key exchange
</li><li>
For end-to-end (destination-to-destination) encryption as a part of <a href="how_elgamalaes">ElGamal/AES+SessionTag</a>
</li><li>
For encryption of some <a href="how_networkdatabase.html#delivery">netDb stores and queries sent to floodfill routers</a>
as a part of <a href="how_elgamalaes">ElGamal/AES+SessionTag</a>
(destination-to-router or router-to-router).
</li><li>
For encryption of <a href="how_tunnelrouting.html#testing">periodic tunnel test messages</a> sent from the router to itself, through its own tunnels.
</li></ul>
</p><p>
We use 256 bit AES in CBC mode.
The padding used is specified in <a href="http://tools.ietf.org/html/rfc2313">IETF RFC-2313 (PKCS#5 1.5, section 8.1 (for block type 02))</a>.
In this case, padding exists of pseudorandomly generated octets to match 16 byte blocks.
@ -124,12 +183,36 @@ Two situations are possible:
2. For situations where we know the size of the data to be sent, we AES encrypt the following:
<p>
<PRE>
|_______1_______2_______3_______4_______5_______6_______7_______8
|H(data)
|
|
| |
| size of data (in bytes) | data ... | rand ... |
+----+----+----+----+----+----+----+----+
| H(data) |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| size | data ... |
+----+----+ +
| |
~ ~
| |
+ +
| |
+ +----//---+----+
| | |
+----+----+----//---+----+ +
| Padding to 16 bytes |
+----+----+----+----+----+----+----+----+
H(data): 32-byte SHA-256 Hash of the data
size: 2-byte Integer, number of data bytes to follow
data: payload
padding: random data, to a multiple of 16 bytes
</PRE>
<p>
After the data comes an application specified number of randomly generated padding bytes.

View File

@ -1,80 +1,329 @@
{% extends "_layout.html" %}
{% block title %}How ElGamal and AES Encryption Work{% endblock %}
{% block content %}<p>
Within I2P, various messages are encrypted, but we don't want anyone to know
to whom or from whom it is bound, so we can't just toss a "to" or "from" address.
In addition, messages are not delivered in order (or reliably), so we can't simply
ElGamal encrypt the first message and AES the subsequent messages. The alternative
of ElGamal encrypting each individual message is daunting in light of the message
frequency desired. Instead, we take each message and evaluate whether it fits into
the three possible conditions:</p>
{% block title %}ElGamal/AES + SessionTag Encryption{% endblock %}
{% block content %}
Updated August 2010, current as of router version 0.8
<h2>Overview</h2>
<p>
ElGamal/AES+SessionTags is used for end-to-end encryption.
</p>
<p> As an unreliable, unordered, message based system, I2P uses a simple combination
of asymmetric and symmetric encryption algorithms to provide data confidentiality
and integrity to garlic messages. As a whole, the combination is referred
to as ElGamal/AES+SessionTags, but that is an excessively verbose way to describe
the use of 2048bit ElGamal, AES256, SHA256, and 32 byte nonces. </p>
<p> The first time a router wants to encrypt a garlic message to another router,
they encrypt the keying material for an AES256 session key with ElGamal and
append the AES256/CBC encrypted payload after that encrypted ElGamal block.
In addition to the encrypted payload, the AES encrypted section contains the
payload length, the SHA256 hash of the unencrypted payload, as well as a number
of "session tags" - random 32 byte nonces. The next time the sender wants
to encrypt a garlic message to another router, rather than ElGamal encrypt
a new session key they simply pick one of the previously delivered session
tags and AES encrypt the payload like before, using the session key used with
that session tag, prepended with the session tag itself. When a router receives
a garlic encrypted message, they check the first 32 bytes to see if it matches
an available session tag - if it does, they simply AES decrypt the message,
but if it does not, they ElGamal decrypt the first block. </p>
<p> Each session tag can be used only once so as to prevent internal adversaries
from unnecessarily correlating different messages as being between the same
routers. The sender of an ElGamal/AES+SessionTag encrypted message chooses
when and how many tags to deliver, prestocking the recipient with enough tags
to cover a volley of messages. Garlic messages may detect the successful tag
delivery by bundling a small additional message as a clove (a "delivery status
message") - when the garlic message arrives at the intended recipient and
is decrypted successfully, this small delivery status message is one of the
cloves exposed and has instructions for the recipient to send the clove back
to the original sender (through an inbound tunnel, of course). When the original
sender receives this delivery status message, they know that the session tags
bundled in the garlic message were successfully delivered. </p>
<p> Session tags themselves have a short lifetime, after which they are
discarded if not used. In addition, the quantity stored for each key is limited,
as are the number of keys themselves - if too many arrive, either new or old
messages may be dropped. The sender keeps track whether messages using session
tags are getting through, and if there isn't sufficient communication it may
drop the ones previously assumed to be properly delivered, reverting back
to the full expensive ElGamal encryption.
A session will continue to exist until all its tags are exhausted or expire.
</p><p>
Sessions are unidirectional. Tags are delivered from Alice to Bob,
and Alice then uses the tags, one by one, in subsequent messages to Bob.
</p><p>
Sessions may be established between Destinations, between Routers, or
between a Router and a Destination.
Each Router and Destination maintains its own Session Key Manager to
keep track of Session Keys and Session Tags.
Separate Session Key Managers prevents correlation of multiple Destinations
to each other or a Router by adversaries.
</p>
<h2>Message Reception</h2>
<p>
Each message received has one of two
the two possible conditions:</p>
<OL>
<li> its ElGamal encrypted to us</li>
<li> its AES encrypted to us</li>
<li> its not encrypted to us</li>
<li> It is part of an existing session and contains a Session Tag and an AES encrypted block</li>
<li> It is for a new session and contains both ElGamal and AES encrypted blocks</li>
</OL>
When a router receives a message, it will first assume it is from
an existing session and attempt to look up the Session Tag and decrypt the following data using AES.
If that fails, it will assume it is for a new session and attempt to
decrypt it using ElGamal.
</p>
<h2 id="new">New Session Message Specification</h2>
<p>
If its ElGamal encrypted to us, the message is considered a new session, and
is encrypted per encryptNewSession(...) in
<a href="http://docs.i2p2.de/core/net/i2p/crypto/ElGamalAESEngine.html">[ElGamalAESEngine]</a>
as follows -</p>
<p>An initial ElGamal block, encrypted <a href="how_cryptography">as before</a>:</p>
An ElGamal Message contains two parts, an encrypted ElGamal block
and an encrypted AES block.
</p><p>
The encrypted message contains:
<PRE>
|_______1_______2_______3_______4_______5_______6_______7_______8
| 32 byte session key
|
|
| |
| 32 byte pre-IV (first 16 bytes of H(pre-IV) == IV)
|
|
| |
| (158 bytes of random data)
| ...
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ElGamal Encrypted Block |
~ ~
| |
+ +----+----+----+----+----+----+
| | |
+----+----+ +
| |
+ +
| AES Encrypted Block |
~ ~
| |
+ +----+----+----+----+----+----+
| +
+----+----+
</PRE>
<p>Followed by the following, AES encrypted <a href="how_cryptography">as before</a>,
using the session key and IV from the header:</p>
</p>
<h3>ElGamal Block</h3>
<p>
The encrypted ElGamal Block is always 514 bytes long.
The encrypted AES Block length is variable but is always a multiple of 16 bytes.
</p><p>
The unencrypted ElGamal data is 222 bytes long, containing:
<PRE>
|_______1_______2_______3_______4_______5_______6_______7_______8
| # session tags| that many sessionTags (32 byte random numbers)
| ...
| | size of the payload (bytes) | H(payload)
|
|
|
| | flag |payload
| ...
| |
| random bytes leaving the total AES block (size % 16 == 0) |
+----+----+----+----+----+----+----+----+
| |
+ +
| Session Key |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| Pre-IV |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
+ +
| |
+ +
| 158 bytes random padding |
~ ~
| |
+ +----+----+
| |
+----+----+----+----+----+----+
</PRE>
The 32-byte
<a href="common_structures_spec#type_SessionKey">Session Key</a>
is the identifier for the session.
The 32-byte Pre-IV will be used to generate the IV for the AES block that follows;
the IV is the first 16 bytes of the SHA-256 Hash of the Pre-IV.
</p><p>
The 222 byte payload is encrypted
<a href="how_cryptography.html#elgamal">using ElGamal</a>
and the encrypted block is 514 bytes long.
</p>
<h3 id="aes">AES Block</h3>
<p>The unencrypted data in the AES block contains the following:
<PRE>
+----+----+----+----+----+----+----+----+
|tag count| |
+----+----+ +
| |
+ +
| Session Tags |
~ ~
| |
+ +
| |
+ +----+----+----+----+----+----+
| | payload size | |
+----+----+----+----+----+----+ +
| |
+ +
| Payload Hash |
+ +
| |
+ +----+----+
| |flag| |
+----+----+----+----+----+----+----+ +
| |
+ +
| New Session Key (opt.) |
+ +
| |
+ +----+
| | |
+----+----+----+----+----+----+----+ +
| |
+ +
| Payload |
~ ~
| |
+ +----//---+----+
| | |
+----+----+----//---+----+ +
| Padding to 16 bytes |
+----+----+----+----+----+----+----+----+
tag count: 2-byte <a href="common_structures_spec#type_Integer">Integer</a>, 0-200
Session Tags: That many 32-byte <a href="common_structures_spec#type_SessionTag">Session Tags</a>
payload size: 4-byte <a href="common_structures_spec#type_Integer">Integer</a>
Payload Hash: The 32-byte SHA256 <a href="common_structures_spec#type_Hash">SHA256 Hash</a> of the payload
flag: A one-byte value. Normally == 0. If == 0x01, a Session Key follows
New Session Key: A 32-byte <a href="common_structures_spec#type_SessionKey">Session Key</a>,
to replace the old key, and is only present if preceding flag is 0x01
Payload: the data
Padding: Random data to a multiple of 16 bytes for the total length.
May contain more than the minimum required padding.
Minimum length: 48 bytes
</PRE>
<p>If the flag is 0x01, it is followed by a new session key, replacing
the old one.</p>
</p><p>
The data is then <a href="how_cryptography">AES Encrypted</a>,
using the session key and IV (calculated from the pre-IV) from the ElGamal section.</p>
<h4>Notes</h4>
<ul>
<li>
Actual max payload length, and max block length, is less than 64 KB; see the<a href="i2np.html">I2NP Overview</a>.
</li><li>
New Session Key is currently unused and is never present.
</li></ul>
<h2 id="existing">Existing Session Message Specification</h2>
<p>The session tags delivered successfully are remembered for a
brief period (30 minutes currently) until they are used (and discarded).
They are used by packaging in a message that is not preceded by an
ElGamal block. Instead, it is encrypted per encryptExistingSession(...) in
<a href="http://docs.i2p2.de/core/net/i2p/crypto/ElGamalAESEngine.html">[ElGamalAESEngine]</a>
as follows -</p>
brief period (15 minutes currently) until they are used or discarded.
A tag is used by packaging one in an Existing Session Message that
contains only an AES encrypted block, and
is not preceded by an
ElGamal block.
</p><p?>
The existing session message is
as follows:
<PRE>
|_______1_______2_______3_______4_______5_______6_______7_______8
| session tag (32 byte random number previously delivered and
| not yet expired or used). the session tag also serves as
| the pre-IV (the first 16 bytes of H(sessionTag) == IV)
| |
</PRE>
+----+----+----+----+----+----+----+----+
| |
+ +
| Session Tag |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| AES Encrypted Block |
~ ~
| |
+ +
| |
+----+----+----+----+----+----+----+----+
Session Tag: A 32-byte <a href="common_structures_spec#type_SessionTag">Session Tag</a>
previously delivered in an AES block
AES Encrypyted Block: As specified <a href="#aes">above</a>.
</PRE>
The session tag also serves as
the pre-IV. The IV is the first 16 bytes of the SHA-256 Hash of the sessionTag.
</p><p>
To decode a message from an existing session, a router looks up the Session Tag to find an
associated Session Key. If the Session Tag is found, the AES block is decrypted using the associated Session Key.
If the tag is not found, the message is assumed to be a <a href="#new">New Session Message</a>.
</p>
<h2 id="future">Future Work</h2>
<p>
There are many possible areas to tune the Session Key Manager's algorithms;
some may interact with the streaming library behavior, or have significant
impact on overal performance.
<ul><li>
Delivery of too many tags at one time may impose substantial overhead for brief streaming connections
or datagrams, and increase the chance of message loss.
We currently deliver 40 tags at a time (1280 bytes).
32 (1024 bytes) may be better for tunnel fragmentation.
</li><li>
A few tags could be delivered in each of several messages, or lots of tags all at once.
</li><li>
It is also important to study and tune
the low-tag thresholds at which more tags are sent.
</li><li>
The number of tags delivered could depend on message size, keeping in mind
the eventual padding to 1KB at the tunnel message layer.
</li><li>
Clients could send an estimate of session lifetime to the router, as an advisory
on the number of tags required.
</li><li>
Delivery of too few tags causes the router to fall back to an expensive ElGamal encryption.
</li><li>
The router may assume delivery of Session Tags, or await acknowledgement before using them;
there are tradeoffs for each strategy.
</li><li>
For very brief messages, almost the full 222 bytes of the pre-IV and padding fields in the ElGamal block
could be used for the entire message, instead of establishing a session.
</li><li>
Evaluate padding strategy; currently we pad to a minimum of 128 bytes.
Would be better to add a few tags to small messages than pad.
</li><li>
Perhaps things could be more efficient if the Session Tag system was bidirectional,
so tags delivered in the 'forward' path could be used in the 'reverse' path,
thus avoiding ElGamal in the initial response.
The router currently plays some tricks like this when sending
tunnel test messages to itself.
</li><li>
Change from Session Tags to
<a href="performance.html#prng">a synchronized PRNG</a>.
</li><li>
Several of these ideas may require a new I2NP message type, or
set a flag in the
<a href="tunnel_message_spec.html#delivery">Delivery Instructions</a>,
or set a magic number in the first few bytes of the Session Key field
and accept a small risk of the random Session Key matching the magic number.
</li></ul>
</p>
<p>Followed by the AES encrypted block above (2 byte # session tags,
that many session tags, sizeof(payload), H(payload), flag, payload,
random padding).</p>
{% endblock %}

View File

@ -75,7 +75,7 @@ perhaps it is not, by itself, enough to justify a change in terminology.
</p><p>
Another difference
from the method described by Freedman with I2P's bundling
from the method described by Freedman
is that the path is unidirectional - there is no "turning point" as seen in onion routing
or mixmaster reply blocks, which greatly simplifies the algorithm and allows for more flexible
and reliable delivery.
@ -147,6 +147,9 @@ Delivery Instructions may specify a Destination, Router, or Tunnel.
Generally, a Garlic Message will contain only one clove.
However, the router will periodically bundle two additional
cloves in the Garlic Message:
<center>
<img src="/_static/images/garliccloves.png" alt="Garlic Message Cloves" />
</center>
<ol><li>
A

View File

@ -230,6 +230,12 @@ this is only relevant for destinations that other people know about - a private
group whose destination is only known to trusted peers does not have to worry,
as an adversary can't "ping" them to mount the attack.</p>
<p>Reference:
<a href="http://blog.torproject.org/blog/one-cell-enough">One Cell Enough</a>
</p>
<h3 id="dos">Denial of service attacks</h3>
<p>There are a whole slew of denial of service attacks available against I2P,

View File

@ -183,7 +183,7 @@ Most applications use 2 or 3 hops as their default.
<h2>Tunnel testing</h2>
<h2 id="testing">Tunnel testing</h2>
<p>All tunnels are periodically tested by their creator by sending a
DeliveryStatusMessage out an outbound tunnel and bound for another inbound tunnel
(testing both tunnels at once). If either fails a number of consecutive tests, it is marked as no longer

View File

@ -132,20 +132,36 @@ Cleartext:
| reply_iv |
+ +
| |
+----+----+----+----+----+----+----+----+----+
|flag| request_time | send_message_id |
+----+----+----+----+----+----+----+----+----+
| padding...
+----+----+----+--//
+----+----+----+----+----+----+----+----+
|flag| request_time | send_msg_id
+----+----+----+----+----+----+----+----+
| |
+----+ +
| 29 bytes padding |
+ +
| |
+ +----+----+
| |
+----+----+----+----+----+----+
encrypted:
ElGamal encrypted:
+----+----+----+----+----+----+----+----+
| toPeer |
+ +
| |
+----+----+----+----+----+----+----+----+
| encrypted data ... |
~ ~
| |
+----+----+----+----+----+----+----+----+
ElGamal and AES encrypted:
+----+----+----+----+----+----+----+----+
| encrypted data ... |
~ ~
| |
+----+----+----+----+----+----+----+----+
{% endfilter %}
</pre>
@ -190,27 +206,41 @@ send_message_id :: Integer
padding :: Data
length -> 29 bytes
source -> random
total length: 222
encrypted:
ElGamal encrypted:
toPeer :: First 16 bytes of the SHA-256 Hash of the peer's router identity
length -> 16 bytes
encrypted_data :: ElGamal-2048 encrypted data
encrypted_data :: ElGamal-2048 encrypted data (see notes)
length -> 512
total length: 528
ElGamal and AES encrypted:
encrypted_data :: ElGamal and AES encrypted data
length -> 528
total length: 528
{% endfilter %}
</pre>
<h4>Notes</h4>
<p>
<ul><li>
In the 512-byte encrypted record,
the ElGamal data contains bytes 1-256 and 258-513 of the
<a href="how_cryptography.html#elgamal">514-byte ElGamal encrypted block</a>.
The two padding bytes from the block (the zero bytes at locations 0 and 257) are removed.
</li><li>
See also the <a href="tunnel-alt-creation.html">tunnel creation specification</a>.
</li></ul>
</p>
@ -220,7 +250,7 @@ total length: 528
unencrypted:
+----+----+----+----+----+----+----+----+
| random data... |
~ ~
| |
+ +----+
| |ret |
@ -235,7 +265,7 @@ bytes 0-526: random data
byte 527 : reply
encrypted:
bytes 0-527: AES-encrypted record(note: same size as BuildRequestRecord!)
bytes 0-527: AES-encrypted record(note: same size as BuildRequestRecord)
total length: 528

View File

@ -1,6 +1,8 @@
{% extends "_layout.html" %}
{% block title %}Performance{% endblock %}
{% block content %}
Updated August 2010, current as of router version 0.8
<p>Probably one of the most frequent things people ask is "how fast is I2P?",
and no one seems to like the answer - "it depends". After trying out I2P, the
next thing they ask is "will it get faster?", and the answer to that is a most
@ -33,7 +35,7 @@ gave us a reference to someone we had never heard of). We can also do some
tuning on what we actually send - how many peers we bounce back (or even if we
bounce back a reply), as well as how many concurrent searches we perform.</p>
<h2>Longer SessionTag lifetime</h2>
<h2>Session Tag Tuning and Improvements</h2>
<p>The way the <a href="how_elgamalaes">ElGamal/AES+SessionTag</a> algorithm
works is by managing a set of random one-time-use 32 byte arrays, and expiring
them if they aren't used quickly enough. If we expire them too soon, we're
@ -44,8 +46,13 @@ tags, even more encryption failures may occur prior to detection). With some
more active detection and feedback driven algorithms, we can safely and more
efficiently tune the lifetime of the tags, replacing the ElGamal encryption with
a trivial AES operation.</p>
<p>
Additional ideas for improving Session Tag delivery are described on the
<a href="how_elgamalaes.html#future">ElGamal/AES+SessionTag page</a>.
</p>
<h2>Migrate sessionTag to synchronized PRNG</h2>
<h2 id="prng">Migrate sessionTag to synchronized PRNG</h2>
<p>Right now, our <a href="how_elgamalaes.html">ElGamal/AES+SessionTag</a>
algorithm works by tagging each encrypted message with a unique random
32 byte nonce (a "session tag"), identifying that message as being encrypted
@ -76,13 +83,12 @@ network and CPU load (due to expensive tunnel creation messages).</p>
<p>
This appears to be an easy fix for high load on the big-bandwidth routers, but
we should not resort to it until we've tuned the tunnel building algorithms further.
However, the 10 minute tunnel lifetime is hardcoded in a few places,
so the code needs to be cleaned up before we could change the duration.
However, the 10 minute tunnel lifetime is hardcoded in quite a few places,
so substantial effort would be required to change the duration.
Also, it would be difficult to maintain backward compatibility with such a change.
</p><p>
A new tunnel build algorithm was introduced in release 0.6.1.32 and it has greatly
reduced the number of tunnel builds. Together with better detection of
unreachable peers and other peer selection strategies implemented in release 0.6.1.33,
the situation is much improved, and there are no current plans to extend tunnel lifetime.
Currently, since the network average tunnel build success rate is fairly high,
there are no current plans to extend tunnel lifetime.
</p>
@ -111,4 +117,8 @@ bandwidth, latency, and CPU usage.</p>
<li>Web controls and monitoring the health of the various streams, as well
as the ability to explicitly close or throttle them.</li>
</ul>
<p>
Additional ideas for improving the streaming library are described on the
<a href="streaming.html#future">streaming library page</a>.
</p>
{% endblock %}

View File

@ -405,7 +405,7 @@ retransmitting lost messages, and the latency and overhead of multiple messages.
<h2>Future Work</h2>
<h2 id="future">Future Work</h2>
The behavior of the streaming library has a profound impact on
application-level performance, and as such, is an important
area for further analysis.

View File

@ -17,9 +17,13 @@ for an overview of the process, including peer selection and ordering methods.
the path of peers in the tunnel, rewritten in place, and transmitted
back to the tunnel creator. This single tunnel message is made up
of a variable number of records (up to 8) - one for each potential peer in
the tunnel. Individual records are asymmetrically encrypted to be
the tunnel. Individual records are asymmetrically
<a href="how_cryptography.html#elgamal">(ElGamal)</a>
encrypted to be
read only by a specific peer along the path, while an additional
symmetric layer of encryption is added at each hop so as to expose
symmetric layer of encryption
<a href="how_cryptography.html#AES">(AES)</a>
is added at each hop so as to expose
the asymmetrically encrypted record only at the appropriate time.</p>
<h3 id="number">Number of Records</h3>
@ -37,7 +41,7 @@ with the desired amount of tunnel length obfuscation.
In the current network, most tunnels are 2 or 3 hops long.
The current implementation uses a 5-record VTBM to build tunnels of 4 hops or less,
and the 8-record TBM for longer tunnels.
The 5-record VTBM (which fits in 3 1KB tunnel messaages) reduces network traffic
The 5-record VTBM (which, when fragmented, fits in three 1KB tunnel messaages) reduces network traffic
and increases build sucess rate, because smaller messages are less likely to be dropped.
<p>
The reply message must be the same type and length as the build message.
@ -56,11 +60,11 @@ Also specified in the
bytes 72-103: AES-256 tunnel layer key
bytes 104-135: AES-256 tunnel IV key
bytes 136-167: AES-256 reply key
bytes 168-183: reply IV
bytes 168-183: AES-256 reply IV
byte 184: flags
bytes 185-188: request time (in hours since the epoch)
bytes 189-192: next message ID
bytes 193-222: uninterpreted / random padding</pre>
bytes 193-221: uninterpreted / random padding</pre>
<p>The next tunnel ID and next router identity hash fields are used to
specify the next hop in the tunnel, though for an outbound tunnel
@ -73,23 +77,44 @@ message ID that the message (or reply) should use.</p>
Bit order: 76543210 (bit 7 is MSB)
bit 7: if set, allow messages from anyone
bit 6: if set, allow messages to anyone, and send the reply to the
specified next hop in a tunnel message
specified next hop in a Tunnel Build Reply Message
bits 5-0: Undefined
</pre>
Bit 7 indicates that the hop will be an inbound gateway (IBGW).
Bit 6 indicates that the hop will be an outbound endpoint (OBEP).
If neither bit is set, the hop will be an intermediate participant.
<h4 id="encryption">Request Encryption</h4>
<h4>Request Record Creation</h4>
<p>
Every hop gets a random Tunnel ID.
The current and next-hop Tunnel IDs are filled in.
Every record gets a random tunnel IV key, and reply IV.
The layer and reply key pairs are generated.
</p>
<h4 id="encryption">Request Record Encryption</h4>
<p>That cleartext record is <a href="how_cryptography.html#elgamal">ElGamal 2048 encrypted</a> with the hop's
public encryption key and formatted into a 528 byte record:</p><pre>
bytes 0-15: First 16 bytes of the SHA-256 of the current hop's router identity
bytes 16-527: ElGamal-2048 encrypted request record</pre>
In the 512-byte encrypted record,
the ElGamal data contains bytes 1-256 and 258-513 of the
<a href="how_cryptography.html#elgamal">514-byte ElGamal encrypted block</a>.
The two padding bytes from the block (the zero bytes at locations 0 and 257) are removed.
<p>Since the cleartext uses the full field, there is no need for
additional padding beyond <code>SHA256(cleartext) + cleartext</code>.</p>
<p>
Each 528-byte record is then iteratively encrypted
(using AES decryption, with the reply key and reply IV for each hop) so that the router identity will only be in cleartext
for the hop in question.
</p>
<h3 id="tunnelCreate.hopProcessing">Hop Processing and Encryption</h3>
<p>When a hop receives a TunnelBuildMessage, it looks through the
@ -103,9 +128,17 @@ are dropped.</p>
<p>After deciding whether they will agree to participate in the tunnel
or not, they replace the record that had contained the request with
an encrypted reply block. All other records are <a href="how_cryptography.html#AES">AES-256/CBC
encrypted</a> with the included reply key and IV (though each is
encrypted separately, rather than chained across records).</p>
an encrypted reply block. All other records are <a href="how_cryptography.html#AES">AES-256
encrypted</a> with the included reply key and IV. Each is
encrypted separately, rather than chained across records.</p>
<p>
Each hop knows only its own response.
If it agrees, it will maintain the tunnel until expiration,
even if it will not be used,
as it cannot know whether all other hops agreed.
</p>
<h4 id="tunnelCreate.replyRecord">Reply Record Specification</h4>
@ -140,19 +173,23 @@ The padding is placed before the status byte:
This is also described in the
<a href="i2np_spec.html#msg_TunnelBuildReply">I2NP spec</a>.
<h3 id="tunnelCreate.requestPreparation">Request Preparation</h3>
<h3 id="tunnelCreate.requestPreparation">Tunnel Build Message Preparation</h3>
<p>When building a new request, all of the records must first be
built and asymmetrically encrypted. Each record should then be
decrypted with the reply keys and IVs of the hops earlier in the
path. That decryption should be run in reverse order so that the
<p>When building a new Tunnel Build Messaage, all of the Build Request Records must first be
built and asymmetrically encrypted using
<a href="how_cryptography.html#elgamal">ElGamal</a>.
Each record is then
premptively decrypted with the reply keys and IVs of the hops earlier in the
path, using
<a href="how_cryptography.html#AES">AES</a>.
That decryption should be run in reverse order so that the
asymmetrically encrypted data will show up in the clear at the
right hop after their predecessor encrypts it.</p>
<p>The excess records not needed for individual requests are simply
filled with random data by the creator.</p>
<h3 id="tunnelCreate.requestDelivery">Request Delivery</h3>
<h3 id="tunnelCreate.requestDelivery">Tunnel Build Message Delivery</h3>
<p>For outbound tunnels, the delivery is done directly from the tunnel
creator to the first hop, packaging up the TunnelBuildMessage as if
@ -163,7 +200,7 @@ If no outbound tunnel is available in that pool, an outbound exploratory tunnel
At startup, when no outbound exploratory tunnel exists yet, a fake 0-hop
outbound tunnel is used.</p>
<h3 id="tunnelCreate.endpointHandling">Endpoint Handling</h3>
<h3 id="tunnelCreate.endpointHandling">Tunnel Build Message Endpoint Handling</h3>
<p>
For creation of an outbound tunnel,
@ -179,10 +216,12 @@ or
(the type of message and number of records must match that of the request)
and delivers it to the
reply tunnel specified within the request record. That reply tunnel
forwards the reply records down to the tunnel creator for
processing, as below.</p>
forwards the Tunnel Build Reply Message back to the tunnel creator,
<a href="tunnel-alt.html#tunnel.operation">just as for any other message</a>.
The tunnel creator then
processes it, as described below.</p>
<p>The reply tunnel was specified by the creator as follows:
<p>The reply tunnel was selected by the creator as follows:
Generally it is an inbound tunnel from the same pool as the new outbound tunnel being built.
If no inbound tunnel is available in that pool, an inbound exploratory tunnel is used.
At startup, when no inbound exploratory tunnel exists yet, a fake 0-hop
@ -191,10 +230,10 @@ inbound tunnel is used.</p>
<p>
For creation of an inbound tunnel,
when the request reaches the inbound endpoint (also known as the
tunnel creator), there is no need to generate an explicit Reply Message, and
tunnel creator), there is no need to generate an explicit Tunnel Build Reply Message, and
the router processes each of the replies, as below.</p>
<h3 id="tunnelCreate.replyProcessing">Reply Processing by the Request Creator</h3>
<h3 id="tunnelCreate.replyProcessing">Tunnel Build Reply Message Processing</h3>
<p>To process the reply records, the creator simply has to AES decrypt
each record individually, using the reply key and IV of each hop in
@ -262,9 +301,12 @@ update</a>
<h2 id="future">Future Work</h2>
<ul>
<li>
It appears that, in the current implementation, the originator leaves one record empty
for itself, which is not necessary. Thus a message of n records can only build a
tunnel of n-1 hops. This is to be researched and verified.
In the current implementation, the originator leaves one record empty
for itself. Thus a message of n records can only build a
tunnel of n-1 hops.
This appears to be necessary for inbound tunnels (where the next-to-last hop
can see the hash prefix for the next hop), but not for outbound tunnels.
This is to be researched and verified.
If it is possible to use the remaining record without compromising anonymity,
we should do so.
<li>
@ -274,7 +316,11 @@ Therefore the request time field is unused.
This should be researched and possibly changed.
<li>
Further analysis of possible tagging and timing attacks described in the above notes.
</ul>
</li><li>
The Bloom filter rotation time should be evaluated.
</li><li>
Use only VTBM; do not select old peers that don't support it.
</li></ul>
{% endblock %}

View File

@ -3,18 +3,18 @@
{% block content %}
This page documents the current tunnel implementation.
Updated July 2010 for release 0.8
Updated September 2010 for release 0.8
<h2>1) <a name="tunnel.overview">Tunnel overview</a></h2>
<h2><a name="tunnel.overview">Tunnel overview</a></h2>
<p>Within I2P, messages are passed in one direction through a virtual
tunnel of peers, using whatever means are available to pass the
message on to the next hop. Messages arrive at the tunnel's
gateway, get bundled up and/or fragmented into fixed sizes tunnel messages,
</i>gateway</i>, get bundled up and/or fragmented into fixed-size tunnel messages,
and are forwarded on to the next hop in the tunnel, which processes and verifies
the validity of the message and sends it on to the next hop, and so on, until
it reaches the tunnel endpoint. That endpoint takes the messages
it reaches the tunnel endpoint. That <i>endpoint</i> takes the messages
bundled up by the gateway and forwards them as instructed - either
to another router, to another tunnel on another router, or locally.</p>
@ -27,8 +27,8 @@ out to the remote endpoint.</p>
<p>The tunnel's creator selects exactly which peers will participate
in the tunnel, and provides each with the necessary configuration
data. They may have any number of hops, but may be constrained with various
proof-of-work requests to add on additional steps. It is the intent to make
data. They may have any number of hops.
It is the intent to make
it hard for either participants or third parties to determine the length of
a tunnel, or even for colluding participants to determine whether they are a
part of the same tunnel at all (barring the situation where colluding peers are
@ -49,31 +49,88 @@ available for client applications, exposing TCP-esque operation,
including message reordering, retransmission, congestion control, etc.</p>
<p>
An overview of I2P terminology is
An overview of I2P tunnel terminology is
<a href="how_tunnelrouting.html">on the tunnel overview page</a>.
</p>
<h2>2) <a name="tunnel.operation">Tunnel operation</a></h2>
<h2><a name="tunnel.operation">Tunnel Operation (Message Processing)</a></h2>
<h3>Overview</h3>
<p>Tunnel operation has four distinct processes, taken on by various
peers in the tunnel. First, the tunnel gateway accumulates a number
of tunnel messages and preprocesses them into something for tunnel
delivery. Next, that gateway encrypts that preprocessed data, then
forwards it to the first hop. That peer, and subsequent tunnel
<p>After a tunnel is built, <a href="i2np.html">I2NP messages</a> are processed and passed through it.
Tunnel operation has four distinct processes, taken on by various
peers in the tunnel. <ol><li>First, the tunnel gateway accumulates a number
of I2NP messages and preprocesses them into tunnel messages for
delivery. </li><li>Next, that gateway encrypts that preprocessed data, then
forwards it to the first hop. </li><li>That peer, and subsequent tunnel
participants, unwrap a layer of the encryption, verifying that it isn't
a duplicate, then forward it on to the next peer.
Eventually, the message arrives at the endpoint where the messages
bundled by the gateway are split out again and forwarded on as
requested.</p>
</li><li>Eventually, the tunnel messages arrive at the endpoint where the I2NP messages
originally bundled by the gateway are reassembled and forwarded on as
requested.</li></ol></p>
<p>Tunnel IDs are 4 byte numbers used at each hop - participants know what
tunnel ID to listen for messages with and what tunnel ID they should be forwarded
on as to the next hop, and each hop chooses the tunnel ID which they receive messages
on. Tunnels themselves are short-lived (10 minutes).
Even if subsequent tunnels are built using the same sequence of
peers, each hop's tunnel ID will change.</p>
<p>
Intermediate tunnel participants do not know whether they are in an
inbound or an outbound tunnel; they always "encrypt" for the next hop.
Therefore, we take advantage of symmetric AES encryption
to "decrypt" at the outbound tunnel gateway,
so that the plaintext is revealed at the outbound endpoint.
</p>
<p>
<center>
<img src="/_static/images/tunnels.png" alt="Inbound and outbound tunnel schematic" title="Inbound and outbound tunnel schematic" />
</center>
</p>
<h3>2.1) <a name="tunnel.preprocessing">Message preprocessing</a></h3>
<table><tr>
<th>Role</th>
<th>Preprocessing</th>
<th>Encryption Operation</th>
<th>Postprocessing</th>
</tr>
<tr><td>Outbound Gateway (Creator)</td>
<td>Fragment, Batch, and Pad</td>
<td>Iteratively encrypt (using decryption operations)</td>
<td>Forward to next hop</td>
</tr>
<tr><td>Participant</td>
<td>&nbsp;</td>
<td>Decrypt (using an encryption operation)</td>
<td>Forward to next hop</td>
</tr>
<tr><td>Outbound Endpoint</td>
<td>&nbsp;</td>
<td>Decrypt (using an encryption operation) to reveal plaintext tunnel message</td>
<td>Reassemble Fragments, Forward as instructed to Inbound Gateway or Router</td>
</tr>
<tr><td colspan="4"><hr></td></tr>
<tr><td>Inbound Gateway</td>
<td>Fragment, Batch, and Pad</td>
<td>Encrypt</td>
<td>Forward to next hop</td>
</tr>
<tr><td>Participant</td>
<td>&nbsp;</td>
<td>Encrypt</td>
<td>Forward to next hop</td>
</tr>
<tr><td>Inbound Endpoint (Creator)</td>
<td>&nbsp;</td>
<td>Iteratively decrypt to reveal plaintext tunnel message</td>
<td>Reassemble Fragments, Receive data</td>
</tr>
</table>
<h3><a name="tunnel.gateway">Gateway Processing</a></h3>
<h4><a name="tunnel.preprocessing">Message Preprocessing</a></h4>
<p>A tunnel gateway's function is to fragment and pack
<a href="i2np.html">I2NP messages</a> into fixed-size
@ -86,9 +143,23 @@ Tunnel messages contain the following:
<li>A 16 byte IV (initialization vector)</li>
<li>A checksum
<li>Padding, if necessary</li>
<li>One or more { delivery instruction, I2NP message fragment} pairs</li>
<li>One or more { delivery instruction, I2NP message fragment } pairs</li>
</ul>
<p>Tunnel IDs are 4 byte numbers used at each hop - participants know what
tunnel ID to listen for messages with and what tunnel ID they should be forwarded
on as to the next hop, and each hop chooses the tunnel ID which they receive messages
on. Tunnels themselves are short-lived (10 minutes).
Even if subsequent tunnels are built using the same sequence of
peers, each hop's tunnel ID will change.</p>
<p>To prevent adversaries from tagging the messages along the path by adjusting
the message size, all tunnel messages are a fixed 1024 bytes in size. To accommodate
larger I2NP messages as well as to support smaller ones more efficiently, the
gateway splits up the larger I2NP messages into fragments contained within each
tunnel message. The endpoint will attempt to rebuild the I2NP message from the
fragments for a short period of time, but will discard them as necessary.</p>
<p>
Details are in the
@ -96,7 +167,7 @@ Details are in the
<h3>2.2) <a name="tunnel.gateway">Gateway Processing</a></h3>
<h4>Gateway Encryption</h3>
<p>After the preprocessing of messages into a padded payload, the gateway builds
a random 16 byte IV value, iteratively encrypting it and the tunnel message as
@ -111,7 +182,7 @@ data with the IV and layer keys for all hops in the tunnel. The result of the o
tunnel encryption is that when each peer encrypts it, the endpoint will recover
the initial preprocessed data.</p>
<h3>2.3) <a name="tunnel.participant">Participant Processing</a></h3>
<h3><a name="tunnel.participant">Participant Processing</a></h3>
<p>When a peer receives a tunnel message, it checks that the message came from
the same previous hop as before (initialized when the first message comes through
@ -134,7 +205,7 @@ false positive. The unique value fed into the Bloom filter is the XOR of the IV
and the first block so as to prevent nonsequential colluding peers in the tunnel
from tagging a message by resending it with the IV and first block switched.</p>
<h3>2.4) <a name="tunnel.endpoint">Endpoint Processing</a></h3>
<h3><a name="tunnel.endpoint">Endpoint Processing</a></h3>
<p>After receiving and validating a tunnel message at the last hop in the tunnel,
how the endpoint recovers the data encoded by the gateway depends upon whether
@ -148,23 +219,6 @@ layer and IV keys of each step in reverse order.</p>
which it may then parse out into the included I2NP messages and forwards them as
requested in their delivery instructions.</p>
<p>These padding strategies can be used on a variety of levels, addressing the
exposure of message size information to different adversaries. After gathering
and reviewing some <a href="http://dev.i2p.net/~jrandom/messageSizes/">statistics</a>
from the 0.4 network, as well as exploring the anonymity tradeoffs, we're starting
with a fixed tunnel message size of 1024 bytes. Within this however, the fragmented
messages themselves are not padded by the tunnel at all (though for end to end
messages, they may be padded as part of the garlic wrapping).</p>
<h3>2.6) <a name="tunnel.fragmentation">Tunnel Fragmentation</a></h3>
<p>To prevent adversaries from tagging the messages along the path by adjusting
the message size, all tunnel messages are a fixed 1024 bytes in size. To accommodate
larger I2NP messages as well as to support smaller ones more efficiently, the
gateway splits up the larger I2NP messages into fragments contained within each
tunnel message. The endpoint will attempt to rebuild the I2NP message from the
fragments for a short period of time, but will discard them as necessary.</p>
<h2><a name="tunnel.building">Tunnel Building</a></h2>
@ -177,7 +231,7 @@ reply. There are three important dimensions to keep in mind when producing
the tunnels: what peers are used (and where), how the requests are sent (and
replies received), and how they are maintained.</p>
<h3>3.1) <a name="tunnel.peerselection">Peer Selection</a></h3>
<h3><a name="tunnel.peerselection">Peer Selection</a></h3>
<p>Beyond the two types of tunnels - inbound and outbound - there are two styles
of peer selection used for different tunnels - exploratory and client.
@ -240,7 +294,7 @@ within a single pool but not between different pools.
New keys are generated at each router restart.
<h3>3.2) <a name="tunnel.request">Request delivery</a></h3>
<h3><a name="tunnel.request">Request delivery</a></h3>
<p>
A multi-hop tunnel is built using a single build message which is repeatedly
@ -272,7 +326,7 @@ the router in question.
For more information on peer profiling, see the
<a href="how_peerselection.html">Peer Profiling and Selection page</a>.
<h3>3.3) <a name="tunnel.pooling">Tunnel Pools</a></h3>
<h3><a name="tunnel.pooling">Tunnel Pools</a></h3>
<p>To allow efficient operation, the router maintains a series of tunnel pools,
each managing a group of tunnels used for a specific purpose with their own
@ -327,4 +381,14 @@ automatically, how much should be configured as a per tunnel or per hop setting,
and how should the tunnel's creator (and in turn, user) control this operation?
All of this is left as unknown, to be worked out for a distant future release.
<h3>Padding</h3>
<p>The padding strategies can be used on a variety of levels, addressing the
exposure of message size information to different adversaries.
The current fixed tunnel message size is 1024 bytes. Within this however, the fragmented
messages themselves are not padded by the tunnel at all, though for end to end
messages, they may be padded as part of the garlic wrapping.</p>
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB