Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
c77994a585 |
@ -1,2 +1 @@
|
||||
docker-run-dev.sh
|
||||
site-updater-docker.sh
|
||||
.git
|
66
.github/workflows/sync.yaml
vendored
66
.github/workflows/sync.yaml
vendored
@ -1,66 +0,0 @@
|
||||
# GitHub Actions workflow file to sync an external repository to this GitHub mirror.
|
||||
# This file was automatically generated by go-github-sync.
|
||||
#
|
||||
# The workflow does the following:
|
||||
# - Runs on a scheduled basis (and can also be triggered manually)
|
||||
# - Clones the GitHub mirror repository
|
||||
# - Fetches changes from the primary external repository
|
||||
# - Applies those changes to the mirror repository
|
||||
# - Pushes the updated content back to the GitHub mirror
|
||||
#
|
||||
# Authentication is handled by the GITHUB_TOKEN secret provided by GitHub Actions.
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate Github Actions Environment
|
||||
run: if [ "$GITHUB_ACTIONS" != "true" ]; then echo 'This script must be run in a GitHub Actions environment.'; exit 1; fi
|
||||
- name: Checkout GitHub Mirror
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Configure Git
|
||||
run: |-
|
||||
git config user.name 'GitHub Actions'
|
||||
git config user.email 'actions@github.com'
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Sync Primary Repository
|
||||
run: |-
|
||||
# Add the primary repository as a remote
|
||||
git remote add primary https://i2pgit.org/I2P_Developers/i2p.www.git
|
||||
|
||||
# Fetch the latest changes from the primary repository
|
||||
git fetch primary
|
||||
|
||||
# Check if the primary branch exists in the primary repository
|
||||
if git ls-remote --heads primary master | grep -q master; then
|
||||
echo "Primary branch master found in primary repository"
|
||||
else
|
||||
echo "Error: Primary branch master not found in primary repository"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're already on the mirror branch
|
||||
if git rev-parse --verify --quiet master; then
|
||||
git checkout master
|
||||
else
|
||||
# Create the mirror branch if it doesn't exist
|
||||
git checkout -b master
|
||||
fi
|
||||
|
||||
|
||||
# Force-apply all changes from primary, overriding any conflicts
|
||||
echo "Performing force sync from primary/master to master"
|
||||
git reset --hard primary/master
|
||||
|
||||
|
||||
# Push changes back to the mirror repository
|
||||
git push origin master
|
||||
name: Sync Primary Repository to GitHub Mirror
|
||||
"on":
|
||||
push: {}
|
||||
schedule:
|
||||
- cron: 0 * * * *
|
||||
workflow_dispatch: {}
|
86
Dockerfile
86
Dockerfile
@ -1,64 +1,40 @@
|
||||
FROM debian:oldoldstable as builder
|
||||
ENV SERVERNAME=geti2p.net \
|
||||
SERVERMAIL=example@geti2p.net
|
||||
|
||||
# Install only build dependencies first
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
python2-dev \
|
||||
python-pip \
|
||||
patch \
|
||||
python-virtualenv \
|
||||
git \
|
||||
python-polib && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# Copy dependency files first for better layer caching
|
||||
COPY etc/reqs.txt etc/
|
||||
COPY etc/multi-domain.patch etc/
|
||||
|
||||
# Setup virtual environment and install dependencies
|
||||
RUN virtualenv --distribute env && \
|
||||
. env/bin/activate && \
|
||||
pip install -r etc/reqs.txt
|
||||
|
||||
# Now copy the rest of the application
|
||||
COPY . .
|
||||
|
||||
# Build steps in a single layer
|
||||
RUN . env/bin/activate && \
|
||||
patch -p0 -N -r - < etc/multi-domain.patch && \
|
||||
./compile-messages.sh && \
|
||||
echo "Git revision: $(git log -n 1 | grep commit | sed 's/commit //' | sed 's/ .*$//')" > ./i2p2www/pages/include/mtnversion
|
||||
|
||||
# Start second stage with same old base image
|
||||
FROM debian:oldoldstable
|
||||
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
apache2 \
|
||||
apache2-utils \
|
||||
libapache2-mod-wsgi \
|
||||
python2-minimal && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
ENV SERVERNAME=geti2p.net
|
||||
ENV SERVERMAIL=example@geti2p.net
|
||||
|
||||
WORKDIR /var/www/i2p.www
|
||||
|
||||
# Copy built artifacts
|
||||
COPY --from=builder /build /var/www/i2p.www
|
||||
COPY --from=builder /build/env /var/www/env
|
||||
## Install the dependencies
|
||||
#RUN #grep -v security.debian /etc/apt/sources.list > /etc/apt/sources.list.bak && \
|
||||
#grep -v stretch-updates /etc/apt/sources.list.bak > /etc/apt/sources.list && \
|
||||
RUN apt-get update && \
|
||||
apt-get -y install apache2 apache2-utils libapache2-mod-wsgi python2-dev python-pip patch python-virtualenv git python-polib
|
||||
|
||||
# Configure Apache and WSGI in a single layer
|
||||
RUN cp etc/docker.wsgi.i2p i2p.wsgi && \
|
||||
chown -R www-data:www-data /var/www/i2p.www && \
|
||||
chmod 755 i2p.wsgi && \
|
||||
cp etc/apache2.i2p.conf /etc/apache2/sites-available/i2p.conf && \
|
||||
a2enmod wsgi && \
|
||||
ADD . /var/www/i2p.www
|
||||
|
||||
## Start setting up the site
|
||||
RUN rm -rfv env && \
|
||||
virtualenv --distribute env && \
|
||||
. env/bin/activate && \
|
||||
pip install -r etc/reqs.txt && \
|
||||
patch -p0 -N -r - <etc/multi-domain.patch && \
|
||||
./compile-messages.sh && \
|
||||
echo "Git revision: $(git log -n 1 | grep commit | sed 's/commit //' | sed 's/ .*$//')" | tee ./i2p2www/pages/include/mtnversion && \
|
||||
## We've now updated the site
|
||||
## Next let's configure WSGI
|
||||
## Set ownership of site to server
|
||||
cp etc/docker.wsgi.i2p i2p.wsgi && \
|
||||
chown -R www-data /var/www/i2p.www && \
|
||||
## Make the WSGI script owned by the server
|
||||
chown www-data:www-data /var/www/i2p.www/i2p.wsgi && \
|
||||
## Make the WSGI script executable
|
||||
chmod 755 /var/www/i2p.www/i2p.wsgi && \
|
||||
## Copy the unmodified vhosts file to the apache2 confdir
|
||||
cp etc/apache2.i2p.conf /etc/apache2/sites-available/i2p.conf && \
|
||||
a2enmod wsgi && \
|
||||
a2ensite i2p && \
|
||||
ls /etc/apache2 && \
|
||||
sed -i 's|IncludeOptional sites-enabled|# IncludeOptional sites-enabled|g' /etc/apache2/apache2.conf && \
|
||||
sed -i '1 i\IncludeOptional sites-enabled/i2p.conf' /etc/apache2/apache2.conf
|
||||
|
||||
CMD service apache2 restart && tail -f /var/log/apache2/access.log /var/log/apache2/error.log
|
||||
CMD service apache2 restart && tail -f /var/log/apache2/access.log
|
||||
|
@ -1,16 +1,190 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 486 560">
|
||||
<style><![CDATA[.B{font-family:Arial}.C{font-size:24px}]]></style>
|
||||
<g fill="#fff" stroke="#000" stroke-width="2">
|
||||
<path d="M23.4 383.8h360v60h-360zm0-60h180v60h-180zm180 0h180v60h-180zm-180-60h180v60h-180zm180 0h180v60h-180zm-180-60h360v60h-360zm0 0"/>
|
||||
<path d="M23.4 143.8h360v60h-360zm0 0"/>
|
||||
<path d="M23.4 83.8h360v60h-360zm0-60h180v60h-180zm180 0h180v60h-180zm0 0"/></g>
|
||||
<text xml:space="preserve" x="36.6" y="37.2" class="B C"><tspan x="59" y="60">Streaming</tspan></text>
|
||||
<text xml:space="preserve" x="211.8" y="37.1" class="B C"><tspan x="234.2" y="59.9">Datagrams</tspan></text>
|
||||
<text xml:space="preserve" x="153.7" y="99.6" class="B C"><tspan x="176.1" y="122.4">I2CP</tspan></text>
|
||||
<text xml:space="preserve" x="89.8" y="157.2" class="B C"><tspan x="112.2" y="180">Garlic Encryption</tspan></text>
|
||||
<text xml:space="preserve" x="51.4" y="279.6" class="B C"><tspan x="73.8" y="302.4">NTCP2</tspan></text><text xml:space="preserve" x="239.7" y="279.6" class="B C"><tspan x="262.1" y="302.4">SSU2</tspan></text>
|
||||
<text xml:space="preserve" x="67.2" y="339.6" class="B C"><tspan x="89.6" y="362.4">TCP</tspan></text>
|
||||
<text xml:space="preserve" x="245.2" y="339.4" class="B C"><tspan x="267.6" y="362.2">UDP</tspan></text>
|
||||
<text xml:space="preserve" x="169.1" y="399.6" class="B C"><tspan x="191.5" y="422.4">IP</tspan></text>
|
||||
<text xml:space="preserve" x="86.9" y="217.1" class="B C"><tspan x="109.3" y="239.9">Tunnel Messages</tspan></text>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="362pt" height="422pt" viewBox="0 0 362 422" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d="M 0.84375 3 L 0.84375 -11.984375 L 9.34375 -11.984375 L 9.34375 3 L 0.84375 3 Z M 1.796875 2.0625 L 8.40625 2.0625 L 8.40625 -11.03125 L 1.796875 -11.03125 L 1.796875 2.0625 Z M 1.796875 2.0625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 1.671875 -12.390625 L 3.34375 -12.390625 L 3.34375 0 L 1.671875 0 L 1.671875 -12.390625 Z M 1.671875 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 3.34375 -11.015625 L 3.34375 -6.359375 L 5.453125 -6.359375 C 6.234375 -6.359375 6.835938 -6.5625 7.265625 -6.96875 C 7.691406 -7.375 7.90625 -7.945312 7.90625 -8.6875 C 7.90625 -9.425781 7.691406 -10 7.265625 -10.40625 C 6.835938 -10.8125 6.234375 -11.015625 5.453125 -11.015625 L 3.34375 -11.015625 Z M 1.671875 -12.390625 L 5.453125 -12.390625 C 6.835938 -12.390625 7.882812 -12.078125 8.59375 -11.453125 C 9.3125 -10.828125 9.671875 -9.90625 9.671875 -8.6875 C 9.671875 -7.46875 9.3125 -6.546875 8.59375 -5.921875 C 7.882812 -5.296875 6.835938 -4.984375 5.453125 -4.984375 L 3.34375 -4.984375 L 3.34375 0 L 1.671875 0 L 1.671875 -12.390625 Z M 1.671875 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M -0.046875 -12.390625 L 10.4375 -12.390625 L 10.4375 -10.984375 L 6.03125 -10.984375 L 6.03125 0 L 4.34375 0 L 4.34375 -10.984375 L -0.046875 -10.984375 L -0.046875 -12.390625 Z M -0.046875 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-4">
|
||||
<path style="stroke:none;" d="M 10.953125 -11.4375 L 10.953125 -9.671875 C 10.390625 -10.191406 9.785156 -10.582031 9.140625 -10.84375 C 8.503906 -11.101562 7.828125 -11.234375 7.109375 -11.234375 C 5.691406 -11.234375 4.601562 -10.800781 3.84375 -9.9375 C 3.09375 -9.070312 2.71875 -7.820312 2.71875 -6.1875 C 2.71875 -4.550781 3.09375 -3.300781 3.84375 -2.4375 C 4.601562 -1.570312 5.691406 -1.140625 7.109375 -1.140625 C 7.828125 -1.140625 8.503906 -1.269531 9.140625 -1.53125 C 9.785156 -1.789062 10.390625 -2.179688 10.953125 -2.703125 L 10.953125 -0.953125 C 10.359375 -0.554688 9.734375 -0.257812 9.078125 -0.0625 C 8.429688 0.132812 7.738281 0.234375 7 0.234375 C 5.125 0.234375 3.644531 -0.335938 2.5625 -1.484375 C 1.488281 -2.628906 0.953125 -4.195312 0.953125 -6.1875 C 0.953125 -8.175781 1.488281 -9.742188 2.5625 -10.890625 C 3.644531 -12.046875 5.125 -12.625 7 -12.625 C 7.75 -12.625 8.445312 -12.523438 9.09375 -12.328125 C 9.75 -12.128906 10.367188 -11.832031 10.953125 -11.4375 Z M 10.953125 -11.4375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-5">
|
||||
<path style="stroke:none;" d="M 1.484375 -12.390625 L 3.15625 -12.390625 L 3.15625 -4.859375 C 3.15625 -3.535156 3.394531 -2.582031 3.875 -2 C 4.363281 -1.414062 5.144531 -1.125 6.21875 -1.125 C 7.300781 -1.125 8.082031 -1.414062 8.5625 -2 C 9.039062 -2.582031 9.28125 -3.535156 9.28125 -4.859375 L 9.28125 -12.390625 L 10.96875 -12.390625 L 10.96875 -4.65625 C 10.96875 -3.039062 10.566406 -1.820312 9.765625 -1 C 8.960938 -0.175781 7.78125 0.234375 6.21875 0.234375 C 4.65625 0.234375 3.472656 -0.175781 2.671875 -1 C 1.878906 -1.820312 1.484375 -3.039062 1.484375 -4.65625 L 1.484375 -12.390625 Z M 1.484375 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-6">
|
||||
<path style="stroke:none;" d="M 3.34375 -11.015625 L 3.34375 -1.375 L 5.375 -1.375 C 7.082031 -1.375 8.332031 -1.757812 9.125 -2.53125 C 9.914062 -3.3125 10.3125 -4.535156 10.3125 -6.203125 C 10.3125 -7.867188 9.914062 -9.085938 9.125 -9.859375 C 8.332031 -10.628906 7.082031 -11.015625 5.375 -11.015625 L 3.34375 -11.015625 Z M 1.671875 -12.390625 L 5.109375 -12.390625 C 7.515625 -12.390625 9.28125 -11.890625 10.40625 -10.890625 C 11.53125 -9.890625 12.09375 -8.328125 12.09375 -6.203125 C 12.09375 -4.066406 11.523438 -2.5 10.390625 -1.5 C 9.265625 -0.5 7.503906 0 5.109375 0 L 1.671875 0 L 1.671875 -12.390625 Z M 1.671875 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-7">
|
||||
<path style="stroke:none;" d="M 1.671875 -12.390625 L 3.921875 -12.390625 L 9.421875 -2.03125 L 9.421875 -12.390625 L 11.046875 -12.390625 L 11.046875 0 L 8.796875 0 L 3.296875 -10.375 L 3.296875 0 L 1.671875 0 L 1.671875 -12.390625 Z M 1.671875 -12.390625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-8">
|
||||
<path style="stroke:none;" d="M 9.09375 -11.984375 L 9.09375 -10.34375 C 8.457031 -10.65625 7.859375 -10.882812 7.296875 -11.03125 C 6.734375 -11.175781 6.1875 -11.25 5.65625 -11.25 C 4.75 -11.25 4.046875 -11.070312 3.546875 -10.71875 C 3.054688 -10.363281 2.8125 -9.863281 2.8125 -9.21875 C 2.8125 -8.664062 2.972656 -8.25 3.296875 -7.96875 C 3.628906 -7.6875 4.253906 -7.460938 5.171875 -7.296875 L 6.1875 -7.09375 C 7.4375 -6.851562 8.359375 -6.429688 8.953125 -5.828125 C 9.546875 -5.234375 9.84375 -4.429688 9.84375 -3.421875 C 9.84375 -2.222656 9.4375 -1.3125 8.625 -0.6875 C 7.820312 -0.0703125 6.644531 0.234375 5.09375 0.234375 C 4.507812 0.234375 3.882812 0.164062 3.21875 0.03125 C 2.5625 -0.09375 1.878906 -0.285156 1.171875 -0.546875 L 1.171875 -2.28125 C 1.847656 -1.894531 2.515625 -1.601562 3.171875 -1.40625 C 3.828125 -1.21875 4.46875 -1.125 5.09375 -1.125 C 6.050781 -1.125 6.789062 -1.3125 7.3125 -1.6875 C 7.832031 -2.0625 8.09375 -2.597656 8.09375 -3.296875 C 8.09375 -3.898438 7.90625 -4.375 7.53125 -4.71875 C 7.15625 -5.0625 6.539062 -5.320312 5.6875 -5.5 L 4.671875 -5.6875 C 3.421875 -5.9375 2.515625 -6.328125 1.953125 -6.859375 C 1.398438 -7.390625 1.125 -8.128906 1.125 -9.078125 C 1.125 -10.171875 1.507812 -11.035156 2.28125 -11.671875 C 3.050781 -12.304688 4.113281 -12.625 5.46875 -12.625 C 6.050781 -12.625 6.644531 -12.566406 7.25 -12.453125 C 7.851562 -12.347656 8.46875 -12.191406 9.09375 -11.984375 Z M 9.09375 -11.984375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-9">
|
||||
<path style="stroke:none;" d="M 1.4375 -3.671875 L 1.4375 -9.296875 L 2.96875 -9.296875 L 2.96875 -3.734375 C 2.96875 -2.847656 3.140625 -2.1875 3.484375 -1.75 C 3.828125 -1.3125 4.34375 -1.09375 5.03125 -1.09375 C 5.851562 -1.09375 6.503906 -1.351562 6.984375 -1.875 C 7.460938 -2.40625 7.703125 -3.125 7.703125 -4.03125 L 7.703125 -9.296875 L 9.234375 -9.296875 L 9.234375 0 L 7.703125 0 L 7.703125 -1.421875 C 7.328125 -0.859375 6.894531 -0.441406 6.40625 -0.171875 C 5.914062 0.0976562 5.347656 0.234375 4.703125 0.234375 C 3.640625 0.234375 2.828125 -0.09375 2.265625 -0.75 C 1.710938 -1.414062 1.4375 -2.390625 1.4375 -3.671875 Z M 5.28125 -9.515625 L 5.28125 -9.515625 Z M 5.28125 -9.515625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-10">
|
||||
<path style="stroke:none;" d="M 9.328125 -5.609375 L 9.328125 0 L 7.796875 0 L 7.796875 -5.5625 C 7.796875 -6.4375 7.625 -7.09375 7.28125 -7.53125 C 6.945312 -7.96875 6.4375 -8.1875 5.75 -8.1875 C 4.914062 -8.1875 4.257812 -7.921875 3.78125 -7.390625 C 3.3125 -6.867188 3.078125 -6.15625 3.078125 -5.25 L 3.078125 0 L 1.546875 0 L 1.546875 -9.296875 L 3.078125 -9.296875 L 3.078125 -7.859375 C 3.441406 -8.410156 3.867188 -8.820312 4.359375 -9.09375 C 4.859375 -9.375 5.429688 -9.515625 6.078125 -9.515625 C 7.148438 -9.515625 7.957031 -9.179688 8.5 -8.515625 C 9.050781 -7.859375 9.328125 -6.890625 9.328125 -5.609375 Z M 9.328125 -5.609375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-11">
|
||||
<path style="stroke:none;" d="M 9.546875 -5.03125 L 9.546875 -4.28125 L 2.53125 -4.28125 C 2.59375 -3.226562 2.90625 -2.425781 3.46875 -1.875 C 4.039062 -1.320312 4.835938 -1.046875 5.859375 -1.046875 C 6.441406 -1.046875 7.007812 -1.117188 7.5625 -1.265625 C 8.113281 -1.410156 8.660156 -1.628906 9.203125 -1.921875 L 9.203125 -0.46875 C 8.648438 -0.238281 8.085938 -0.0664062 7.515625 0.046875 C 6.941406 0.171875 6.359375 0.234375 5.765625 0.234375 C 4.273438 0.234375 3.097656 -0.191406 2.234375 -1.046875 C 1.367188 -1.910156 0.9375 -3.082031 0.9375 -4.5625 C 0.9375 -6.082031 1.347656 -7.285156 2.171875 -8.171875 C 2.992188 -9.066406 4.101562 -9.515625 5.5 -9.515625 C 6.75 -9.515625 7.734375 -9.113281 8.453125 -8.3125 C 9.179688 -7.507812 9.546875 -6.414062 9.546875 -5.03125 Z M 8.03125 -5.484375 C 8.019531 -6.316406 7.785156 -6.976562 7.328125 -7.46875 C 6.867188 -7.96875 6.265625 -8.21875 5.515625 -8.21875 C 4.660156 -8.21875 3.976562 -7.976562 3.46875 -7.5 C 2.957031 -7.019531 2.660156 -6.34375 2.578125 -5.46875 L 8.03125 -5.484375 Z M 8.03125 -5.484375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-12">
|
||||
<path style="stroke:none;" d="M 1.609375 -12.921875 L 3.125 -12.921875 L 3.125 0 L 1.609375 0 L 1.609375 -12.921875 Z M 1.609375 -12.921875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-13">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-14">
|
||||
<path style="stroke:none;" d="M 8.84375 -7.515625 C 9.21875 -8.203125 9.671875 -8.707031 10.203125 -9.03125 C 10.734375 -9.351562 11.363281 -9.515625 12.09375 -9.515625 C 13.050781 -9.515625 13.789062 -9.175781 14.3125 -8.5 C 14.84375 -7.820312 15.109375 -6.859375 15.109375 -5.609375 L 15.109375 0 L 13.578125 0 L 13.578125 -5.5625 C 13.578125 -6.445312 13.421875 -7.101562 13.109375 -7.53125 C 12.796875 -7.96875 12.3125 -8.1875 11.65625 -8.1875 C 10.863281 -8.1875 10.238281 -7.921875 9.78125 -7.390625 C 9.320312 -6.867188 9.09375 -6.15625 9.09375 -5.25 L 9.09375 0 L 7.5625 0 L 7.5625 -5.5625 C 7.5625 -6.457031 7.398438 -7.117188 7.078125 -7.546875 C 6.765625 -7.972656 6.28125 -8.1875 5.625 -8.1875 C 4.84375 -8.1875 4.222656 -7.921875 3.765625 -7.390625 C 3.304688 -6.867188 3.078125 -6.15625 3.078125 -5.25 L 3.078125 0 L 1.546875 0 L 1.546875 -9.296875 L 3.078125 -9.296875 L 3.078125 -7.859375 C 3.429688 -8.421875 3.847656 -8.835938 4.328125 -9.109375 C 4.816406 -9.378906 5.394531 -9.515625 6.0625 -9.515625 C 6.738281 -9.515625 7.3125 -9.34375 7.78125 -9 C 8.257812 -8.65625 8.613281 -8.160156 8.84375 -7.515625 Z M 8.84375 -7.515625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-15">
|
||||
<path style="stroke:none;" d="M 7.53125 -9.015625 L 7.53125 -7.578125 C 7.09375 -7.796875 6.640625 -7.960938 6.171875 -8.078125 C 5.710938 -8.191406 5.234375 -8.25 4.734375 -8.25 C 3.984375 -8.25 3.414062 -8.128906 3.03125 -7.890625 C 2.65625 -7.660156 2.46875 -7.3125 2.46875 -6.84375 C 2.46875 -6.488281 2.601562 -6.210938 2.875 -6.015625 C 3.144531 -5.816406 3.6875 -5.625 4.5 -5.4375 L 5.03125 -5.328125 C 6.113281 -5.085938 6.882812 -4.753906 7.34375 -4.328125 C 7.800781 -3.910156 8.03125 -3.320312 8.03125 -2.5625 C 8.03125 -1.695312 7.6875 -1.015625 7 -0.515625 C 6.320312 -0.015625 5.382812 0.234375 4.1875 0.234375 C 3.6875 0.234375 3.164062 0.1875 2.625 0.09375 C 2.082031 0 1.515625 -0.144531 0.921875 -0.34375 L 0.921875 -1.921875 C 1.484375 -1.628906 2.035156 -1.40625 2.578125 -1.25 C 3.128906 -1.101562 3.675781 -1.03125 4.21875 -1.03125 C 4.9375 -1.03125 5.488281 -1.15625 5.875 -1.40625 C 6.257812 -1.65625 6.453125 -2.003906 6.453125 -2.453125 C 6.453125 -2.867188 6.3125 -3.1875 6.03125 -3.40625 C 5.757812 -3.625 5.148438 -3.835938 4.203125 -4.046875 L 3.671875 -4.171875 C 2.722656 -4.367188 2.035156 -4.671875 1.609375 -5.078125 C 1.191406 -5.492188 0.984375 -6.0625 0.984375 -6.78125 C 0.984375 -7.65625 1.289062 -8.328125 1.90625 -8.796875 C 2.53125 -9.273438 3.414062 -9.515625 4.5625 -9.515625 C 5.125 -9.515625 5.648438 -9.472656 6.140625 -9.390625 C 6.640625 -9.304688 7.101562 -9.179688 7.53125 -9.015625 Z M 7.53125 -9.015625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-16">
|
||||
<path style="stroke:none;" d="M 5.828125 -4.671875 C 4.585938 -4.671875 3.726562 -4.53125 3.25 -4.25 C 2.78125 -3.96875 2.546875 -3.488281 2.546875 -2.8125 C 2.546875 -2.269531 2.722656 -1.835938 3.078125 -1.515625 C 3.441406 -1.191406 3.929688 -1.03125 4.546875 -1.03125 C 5.390625 -1.03125 6.066406 -1.332031 6.578125 -1.9375 C 7.085938 -2.539062 7.34375 -3.335938 7.34375 -4.328125 L 7.34375 -4.671875 L 5.828125 -4.671875 Z M 8.875 -5.296875 L 8.875 0 L 7.34375 0 L 7.34375 -1.40625 C 7 -0.84375 6.566406 -0.425781 6.046875 -0.15625 C 5.523438 0.101562 4.890625 0.234375 4.140625 0.234375 C 3.179688 0.234375 2.421875 -0.03125 1.859375 -0.5625 C 1.296875 -1.09375 1.015625 -1.804688 1.015625 -2.703125 C 1.015625 -3.753906 1.363281 -4.546875 2.0625 -5.078125 C 2.769531 -5.609375 3.816406 -5.875 5.203125 -5.875 L 7.34375 -5.875 L 7.34375 -6.015625 C 7.34375 -6.722656 7.109375 -7.265625 6.640625 -7.640625 C 6.179688 -8.023438 5.535156 -8.21875 4.703125 -8.21875 C 4.171875 -8.21875 3.65625 -8.15625 3.15625 -8.03125 C 2.65625 -7.90625 2.171875 -7.71875 1.703125 -7.46875 L 1.703125 -8.875 C 2.265625 -9.09375 2.804688 -9.253906 3.328125 -9.359375 C 3.859375 -9.460938 4.367188 -9.515625 4.859375 -9.515625 C 6.203125 -9.515625 7.207031 -9.164062 7.875 -8.46875 C 8.539062 -7.769531 8.875 -6.710938 8.875 -5.296875 Z M 8.875 -5.296875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-17">
|
||||
<path style="stroke:none;" d="M 7.71875 -4.75 C 7.71875 -5.863281 7.488281 -6.722656 7.03125 -7.328125 C 6.570312 -7.941406 5.929688 -8.25 5.109375 -8.25 C 4.296875 -8.25 3.660156 -7.941406 3.203125 -7.328125 C 2.742188 -6.722656 2.515625 -5.863281 2.515625 -4.75 C 2.515625 -3.65625 2.742188 -2.800781 3.203125 -2.1875 C 3.660156 -1.582031 4.296875 -1.28125 5.109375 -1.28125 C 5.929688 -1.28125 6.570312 -1.582031 7.03125 -2.1875 C 7.488281 -2.800781 7.71875 -3.65625 7.71875 -4.75 Z M 9.25 -1.15625 C 9.25 0.425781 8.894531 1.601562 8.1875 2.375 C 7.488281 3.144531 6.414062 3.53125 4.96875 3.53125 C 4.425781 3.53125 3.914062 3.488281 3.4375 3.40625 C 2.96875 3.332031 2.507812 3.210938 2.0625 3.046875 L 2.0625 1.5625 C 2.507812 1.800781 2.953125 1.976562 3.390625 2.09375 C 3.828125 2.21875 4.269531 2.28125 4.71875 2.28125 C 5.71875 2.28125 6.46875 2.015625 6.96875 1.484375 C 7.46875 0.960938 7.71875 0.175781 7.71875 -0.875 L 7.71875 -1.640625 C 7.40625 -1.085938 7 -0.675781 6.5 -0.40625 C 6.007812 -0.132812 5.421875 0 4.734375 0 C 3.597656 0 2.679688 -0.429688 1.984375 -1.296875 C 1.285156 -2.171875 0.9375 -3.320312 0.9375 -4.75 C 0.9375 -6.195312 1.285156 -7.351562 1.984375 -8.21875 C 2.679688 -9.082031 3.597656 -9.515625 4.734375 -9.515625 C 5.421875 -9.515625 6.007812 -9.378906 6.5 -9.109375 C 7 -8.835938 7.40625 -8.429688 7.71875 -7.890625 L 7.71875 -9.296875 L 9.25 -9.296875 L 9.25 -1.15625 Z M 9.25 -1.15625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-18">
|
||||
<path style="stroke:none;" d="M 10.125 -1.765625 L 10.125 -5.09375 L 7.375 -5.09375 L 7.375 -6.46875 L 11.78125 -6.46875 L 11.78125 -1.15625 C 11.132812 -0.695312 10.421875 -0.347656 9.640625 -0.109375 C 8.859375 0.117188 8.023438 0.234375 7.140625 0.234375 C 5.203125 0.234375 3.6875 -0.328125 2.59375 -1.453125 C 1.5 -2.585938 0.953125 -4.164062 0.953125 -6.1875 C 0.953125 -8.207031 1.5 -9.785156 2.59375 -10.921875 C 3.6875 -12.054688 5.203125 -12.625 7.140625 -12.625 C 7.941406 -12.625 8.707031 -12.519531 9.4375 -12.3125 C 10.164062 -12.113281 10.835938 -11.820312 11.453125 -11.4375 L 11.453125 -9.65625 C 10.835938 -10.175781 10.179688 -10.566406 9.484375 -10.828125 C 8.785156 -11.097656 8.050781 -11.234375 7.28125 -11.234375 C 5.757812 -11.234375 4.617188 -10.8125 3.859375 -9.96875 C 3.097656 -9.125 2.71875 -7.863281 2.71875 -6.1875 C 2.71875 -4.507812 3.097656 -3.25 3.859375 -2.40625 C 4.617188 -1.5625 5.757812 -1.140625 7.28125 -1.140625 C 7.875 -1.140625 8.398438 -1.1875 8.859375 -1.28125 C 9.328125 -1.382812 9.75 -1.546875 10.125 -1.765625 Z M 10.125 -1.765625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-19">
|
||||
<path style="stroke:none;" d="M 6.984375 -7.875 C 6.816406 -7.96875 6.628906 -8.035156 6.421875 -8.078125 C 6.222656 -8.128906 6.003906 -8.15625 5.765625 -8.15625 C 4.898438 -8.15625 4.234375 -7.875 3.765625 -7.3125 C 3.304688 -6.75 3.078125 -5.941406 3.078125 -4.890625 L 3.078125 0 L 1.546875 0 L 1.546875 -9.296875 L 3.078125 -9.296875 L 3.078125 -7.859375 C 3.398438 -8.421875 3.816406 -8.835938 4.328125 -9.109375 C 4.847656 -9.378906 5.472656 -9.515625 6.203125 -9.515625 C 6.304688 -9.515625 6.421875 -9.507812 6.546875 -9.5 C 6.679688 -9.488281 6.828125 -9.46875 6.984375 -9.4375 L 6.984375 -7.875 Z M 6.984375 -7.875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-20">
|
||||
<path style="stroke:none;" d="M 1.609375 -9.296875 L 3.125 -9.296875 L 3.125 0 L 1.609375 0 L 1.609375 -9.296875 Z M 1.609375 -12.921875 L 3.125 -12.921875 L 3.125 -10.984375 L 1.609375 -10.984375 L 1.609375 -12.921875 Z M 1.609375 -12.921875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-21">
|
||||
<path style="stroke:none;" d="M 8.296875 -8.9375 L 8.296875 -7.515625 C 7.859375 -7.753906 7.421875 -7.929688 6.984375 -8.046875 C 6.554688 -8.160156 6.117188 -8.21875 5.671875 -8.21875 C 4.679688 -8.21875 3.910156 -7.90625 3.359375 -7.28125 C 2.816406 -6.65625 2.546875 -5.773438 2.546875 -4.640625 C 2.546875 -3.503906 2.816406 -2.617188 3.359375 -1.984375 C 3.910156 -1.359375 4.679688 -1.046875 5.671875 -1.046875 C 6.117188 -1.046875 6.554688 -1.101562 6.984375 -1.21875 C 7.421875 -1.34375 7.859375 -1.523438 8.296875 -1.765625 L 8.296875 -0.359375 C 7.867188 -0.160156 7.425781 -0.015625 6.96875 0.078125 C 6.507812 0.179688 6.023438 0.234375 5.515625 0.234375 C 4.109375 0.234375 2.992188 -0.203125 2.171875 -1.078125 C 1.347656 -1.960938 0.9375 -3.148438 0.9375 -4.640625 C 0.9375 -6.160156 1.351562 -7.351562 2.1875 -8.21875 C 3.019531 -9.082031 4.160156 -9.515625 5.609375 -9.515625 C 6.078125 -9.515625 6.535156 -9.46875 6.984375 -9.375 C 7.429688 -9.28125 7.867188 -9.132812 8.296875 -8.9375 Z M 8.296875 -8.9375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-22">
|
||||
<path style="stroke:none;" d="M 5.46875 0.859375 C 5.039062 1.972656 4.617188 2.695312 4.203125 3.03125 C 3.796875 3.363281 3.25 3.53125 2.5625 3.53125 L 1.34375 3.53125 L 1.34375 2.265625 L 2.234375 2.265625 C 2.660156 2.265625 2.988281 2.160156 3.21875 1.953125 C 3.445312 1.753906 3.707031 1.285156 4 0.546875 L 4.265625 -0.15625 L 0.5 -9.296875 L 2.125 -9.296875 L 5.03125 -2.03125 L 7.9375 -9.296875 L 9.546875 -9.296875 L 5.46875 0.859375 Z M 5.46875 0.859375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-23">
|
||||
<path style="stroke:none;" d="M 3.078125 -1.390625 L 3.078125 3.53125 L 1.546875 3.53125 L 1.546875 -9.296875 L 3.078125 -9.296875 L 3.078125 -7.890625 C 3.398438 -8.441406 3.804688 -8.847656 4.296875 -9.109375 C 4.785156 -9.378906 5.367188 -9.515625 6.046875 -9.515625 C 7.179688 -9.515625 8.097656 -9.066406 8.796875 -8.171875 C 9.503906 -7.273438 9.859375 -6.097656 9.859375 -4.640625 C 9.859375 -3.179688 9.503906 -2.003906 8.796875 -1.109375 C 8.097656 -0.210938 7.179688 0.234375 6.046875 0.234375 C 5.367188 0.234375 4.785156 0.101562 4.296875 -0.15625 C 3.804688 -0.425781 3.398438 -0.835938 3.078125 -1.390625 Z M 8.28125 -4.640625 C 8.28125 -5.765625 8.046875 -6.644531 7.578125 -7.28125 C 7.117188 -7.925781 6.484375 -8.25 5.671875 -8.25 C 4.867188 -8.25 4.234375 -7.925781 3.765625 -7.28125 C 3.304688 -6.644531 3.078125 -5.765625 3.078125 -4.640625 C 3.078125 -3.515625 3.304688 -2.628906 3.765625 -1.984375 C 4.234375 -1.347656 4.867188 -1.03125 5.671875 -1.03125 C 6.484375 -1.03125 7.117188 -1.347656 7.578125 -1.984375 C 8.046875 -2.628906 8.28125 -3.515625 8.28125 -4.640625 Z M 8.28125 -4.640625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-24">
|
||||
<path style="stroke:none;" d="M 3.109375 -11.9375 L 3.109375 -9.296875 L 6.265625 -9.296875 L 6.265625 -8.109375 L 3.109375 -8.109375 L 3.109375 -3.0625 C 3.109375 -2.300781 3.210938 -1.8125 3.421875 -1.59375 C 3.628906 -1.382812 4.050781 -1.28125 4.6875 -1.28125 L 6.265625 -1.28125 L 6.265625 0 L 4.6875 0 C 3.507812 0 2.695312 -0.21875 2.25 -0.65625 C 1.800781 -1.09375 1.578125 -1.894531 1.578125 -3.0625 L 1.578125 -8.109375 L 0.453125 -8.109375 L 0.453125 -9.296875 L 1.578125 -9.296875 L 1.578125 -11.9375 L 3.109375 -11.9375 Z M 3.109375 -11.9375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-25">
|
||||
<path style="stroke:none;" d="M 5.203125 -8.21875 C 4.378906 -8.21875 3.726562 -7.898438 3.25 -7.265625 C 2.78125 -6.628906 2.546875 -5.753906 2.546875 -4.640625 C 2.546875 -3.523438 2.78125 -2.644531 3.25 -2 C 3.726562 -1.363281 4.378906 -1.046875 5.203125 -1.046875 C 6.015625 -1.046875 6.660156 -1.367188 7.140625 -2.015625 C 7.617188 -2.660156 7.859375 -3.535156 7.859375 -4.640625 C 7.859375 -5.742188 7.617188 -6.613281 7.140625 -7.25 C 6.660156 -7.894531 6.015625 -8.21875 5.203125 -8.21875 Z M 5.203125 -9.515625 C 6.535156 -9.515625 7.578125 -9.082031 8.328125 -8.21875 C 9.085938 -7.363281 9.46875 -6.171875 9.46875 -4.640625 C 9.46875 -3.117188 9.085938 -1.925781 8.328125 -1.0625 C 7.578125 -0.195312 6.535156 0.234375 5.203125 0.234375 C 3.867188 0.234375 2.820312 -0.195312 2.0625 -1.0625 C 1.3125 -1.925781 0.9375 -3.117188 0.9375 -4.640625 C 0.9375 -6.171875 1.3125 -7.363281 2.0625 -8.21875 C 2.820312 -9.082031 3.867188 -9.515625 5.203125 -9.515625 Z M 5.203125 -9.515625 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-26">
|
||||
<path style="stroke:none;" d="M 3.265625 -1.40625 L 9.109375 -1.40625 L 9.109375 0 L 1.25 0 L 1.25 -1.40625 C 1.882812 -2.070312 2.75 -2.957031 3.84375 -4.0625 C 4.945312 -5.175781 5.640625 -5.890625 5.921875 -6.203125 C 6.453125 -6.804688 6.820312 -7.316406 7.03125 -7.734375 C 7.25 -8.160156 7.359375 -8.570312 7.359375 -8.96875 C 7.359375 -9.632812 7.128906 -10.171875 6.671875 -10.578125 C 6.210938 -10.992188 5.609375 -11.203125 4.859375 -11.203125 C 4.335938 -11.203125 3.785156 -11.109375 3.203125 -10.921875 C 2.617188 -10.742188 1.992188 -10.472656 1.328125 -10.109375 L 1.328125 -11.796875 C 2.003906 -12.066406 2.632812 -12.269531 3.21875 -12.40625 C 3.800781 -12.550781 4.335938 -12.625 4.828125 -12.625 C 6.109375 -12.625 7.128906 -12.300781 7.890625 -11.65625 C 8.660156 -11.007812 9.046875 -10.148438 9.046875 -9.078125 C 9.046875 -8.566406 8.945312 -8.082031 8.75 -7.625 C 8.5625 -7.175781 8.21875 -6.640625 7.71875 -6.015625 C 7.582031 -5.859375 7.140625 -5.394531 6.390625 -4.625 C 5.648438 -3.863281 4.609375 -2.789062 3.265625 -1.40625 Z M 3.265625 -1.40625 "/>
|
||||
</symbol>
|
||||
</g>
|
||||
</defs>
|
||||
<g id="surface0">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0 0 L 661 0 L 661 401 L 0 401 Z M 0 0 "/>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 17 L 33 17 L 33 20 L 15 20 Z M 15 17 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="173.402344" y="396.875"/>
|
||||
<use xlink:href="#glyph0-2" x="178.402344" y="396.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 14 L 24 14 L 24 17 L 15 17 Z M 15 14 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 24 14 L 33 14 L 33 17 L 24 17 Z M 24 14 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="84.671875" y="336.875"/>
|
||||
<use xlink:href="#glyph0-4" x="84.671875" y="336.875"/>
|
||||
<use xlink:href="#glyph0-2" x="96.488281" y="336.875"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-5" x="253.207031" y="336.875"/>
|
||||
<use xlink:href="#glyph0-6" x="265.589844" y="336.875"/>
|
||||
<use xlink:href="#glyph0-2" x="278.617188" y="336.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 11 L 24 11 L 24 14 L 15 14 Z M 15 11 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 24 11 L 33 11 L 33 14 L 24 14 Z M 24 11 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-7" x="68.988281" y="276.875"/>
|
||||
<use xlink:href="#glyph0-3" x="91" y="276.875"/>
|
||||
<use xlink:href="#glyph0-4" x="91" y="276.875"/>
|
||||
<use xlink:href="#glyph0-2" x="102.816406" y="276.875"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-8" x="254.066406" y="276.875"/>
|
||||
<use xlink:href="#glyph0-8" x="264.808594" y="276.875"/>
|
||||
<use xlink:href="#glyph0-5" x="275.550781" y="276.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 8 L 33 8 L 33 11 L 15 11 Z M 15 8 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="132.71875" y="216.875"/>
|
||||
<use xlink:href="#glyph0-9" x="132.71875" y="216.875"/>
|
||||
<use xlink:href="#glyph0-10" x="143.441406" y="216.875"/>
|
||||
<use xlink:href="#glyph0-10" x="154.164062" y="216.875"/>
|
||||
<use xlink:href="#glyph0-11" x="164.886719" y="216.875"/>
|
||||
<use xlink:href="#glyph0-12" x="175.296875" y="216.875"/>
|
||||
<use xlink:href="#glyph0-13" x="180.003906" y="216.875"/>
|
||||
<use xlink:href="#glyph0-14" x="185.375" y="216.875"/>
|
||||
<use xlink:href="#glyph0-11" x="201.859375" y="216.875"/>
|
||||
<use xlink:href="#glyph0-15" x="212.269531" y="216.875"/>
|
||||
<use xlink:href="#glyph0-15" x="221.078125" y="216.875"/>
|
||||
<use xlink:href="#glyph0-16" x="229.886719" y="216.875"/>
|
||||
<use xlink:href="#glyph0-17" x="240.257812" y="216.875"/>
|
||||
<use xlink:href="#glyph0-11" x="251" y="216.875"/>
|
||||
<use xlink:href="#glyph0-15" x="261.410156" y="216.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 5 L 33 5 L 33 8 L 15 8 Z M 15 5 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-18" x="108.460938" y="156.875"/>
|
||||
<use xlink:href="#glyph0-16" x="121.566406" y="156.875"/>
|
||||
<use xlink:href="#glyph0-19" x="131.9375" y="156.875"/>
|
||||
<use xlink:href="#glyph0-12" x="138.890625" y="156.875"/>
|
||||
<use xlink:href="#glyph0-20" x="143.597656" y="156.875"/>
|
||||
<use xlink:href="#glyph0-21" x="148.304688" y="156.875"/>
|
||||
<use xlink:href="#glyph0-13" x="157.601562" y="156.875"/>
|
||||
<use xlink:href="#glyph0-11" x="162.972656" y="156.875"/>
|
||||
<use xlink:href="#glyph0-10" x="173.382812" y="156.875"/>
|
||||
<use xlink:href="#glyph0-21" x="184.105469" y="156.875"/>
|
||||
<use xlink:href="#glyph0-19" x="193.402344" y="156.875"/>
|
||||
<use xlink:href="#glyph0-22" x="200.355469" y="156.875"/>
|
||||
<use xlink:href="#glyph0-23" x="210.375" y="156.875"/>
|
||||
<use xlink:href="#glyph0-24" x="221.117188" y="156.875"/>
|
||||
<use xlink:href="#glyph0-20" x="227.757812" y="156.875"/>
|
||||
<use xlink:href="#glyph0-25" x="232.464844" y="156.875"/>
|
||||
<use xlink:href="#glyph0-10" x="242.816406" y="156.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 2 L 33 2 L 33 5 L 15 5 Z M 15 2 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="162.113281" y="96.875"/>
|
||||
<use xlink:href="#glyph0-26" x="167.113281" y="96.875"/>
|
||||
<use xlink:href="#glyph0-4" x="177.875" y="96.875"/>
|
||||
<use xlink:href="#glyph0-2" x="189.691406" y="96.875"/>
|
||||
</g>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 -1 L 24 -1 L 24 2 L 15 2 Z M 15 -1 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 24 -1 L 33 -1 L 33 2 L 24 2 Z M 24 -1 " transform="matrix(20,0,0,20,-299,21)"/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-8" x="50.472656" y="36.875"/>
|
||||
<use xlink:href="#glyph0-24" x="61.214844" y="36.875"/>
|
||||
<use xlink:href="#glyph0-19" x="68.089844" y="36.875"/>
|
||||
<use xlink:href="#glyph0-11" x="68.089844" y="36.875"/>
|
||||
<use xlink:href="#glyph0-16" x="78.5" y="36.875"/>
|
||||
<use xlink:href="#glyph0-14" x="88.871094" y="36.875"/>
|
||||
<use xlink:href="#glyph0-20" x="105.355469" y="36.875"/>
|
||||
<use xlink:href="#glyph0-10" x="110.0625" y="36.875"/>
|
||||
<use xlink:href="#glyph0-17" x="120.785156" y="36.875"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-6" x="224.125" y="36.875"/>
|
||||
<use xlink:href="#glyph0-16" x="237.152344" y="36.875"/>
|
||||
<use xlink:href="#glyph0-24" x="247.523438" y="36.875"/>
|
||||
<use xlink:href="#glyph0-16" x="254.164062" y="36.875"/>
|
||||
<use xlink:href="#glyph0-17" x="264.535156" y="36.875"/>
|
||||
<use xlink:href="#glyph0-19" x="275.277344" y="36.875"/>
|
||||
<use xlink:href="#glyph0-16" x="282.230469" y="36.875"/>
|
||||
<use xlink:href="#glyph0-14" x="292.601562" y="36.875"/>
|
||||
<use xlink:href="#glyph0-15" x="309.085938" y="36.875"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 29 KiB |
@ -1,3 +1,56 @@
|
||||
#! /usr/bin/env bash
|
||||
export devmode="--volume $(pwd):/var/www/i2p.www"
|
||||
./site-updater-docker.sh runserver.sh
|
||||
|
||||
## Set additional docker run arguments by changing the variable
|
||||
## i2p_www_docker_run_args in an optional file called config.sh
|
||||
## for example
|
||||
##
|
||||
##i2p_www_docker_run_args='-d'
|
||||
## to run the site in the background, or
|
||||
##
|
||||
##i2p_www_docker_run_args='-t'
|
||||
## to emulate a TTY
|
||||
|
||||
## To operate a quick and easy mirror of the I2P Site in a container
|
||||
## simply clone the i2p.www source to a host with Docker installed, then
|
||||
## add:
|
||||
##
|
||||
##i2p_www_docker_run_args='-d'
|
||||
## to config.sh
|
||||
##
|
||||
## Then add:
|
||||
##
|
||||
##*/10 * * * * /path/to/i2p.www/site-updater-docker.sh
|
||||
##
|
||||
## to a crontab belonging to a member of the `docker` group. To add yourself
|
||||
## to the `docker` group use the command:
|
||||
##
|
||||
##sudo adduser $(whoami) docker
|
||||
##
|
||||
## a more secure solution may be to create a user especially to run the
|
||||
## docker crontab only, who is a member of the docker group. To do this,
|
||||
##
|
||||
##sudo adduser --disabled-password --disabled-login --ingroup docker docker
|
||||
## however the specifics may vary from distribution to distribution.
|
||||
|
||||
dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
|
||||
if [ -f "${dir}/config.sh" ]; then
|
||||
. "${dir}/config.sh"
|
||||
fi
|
||||
|
||||
if [ -z $port ]; then
|
||||
port="8090"
|
||||
fi
|
||||
|
||||
if [ -z $i2p_www_branch ]; then
|
||||
i2p_www_branch=master
|
||||
fi
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" || exit
|
||||
cd "$DIR" || exit
|
||||
|
||||
git pull origin $i2p_www_branch
|
||||
docker build $i2p_www_docker_build_args -t mirror.i2p.www$suffix .
|
||||
docker rm -f mirror.i2p.www$suffix
|
||||
docker run -it $i2p_www_docker_run_args --env DEV:on --name mirror.i2p.www$suffix --net=host --volume $(pwd)/env:/env mirror.i2p.www$suffix ./runserver.py
|
||||
docker logs -f mirror.i2p.www$suffix
|
||||
|
@ -3,5 +3,5 @@ export spec=""
|
||||
export venv="`which virtualenv-2.7`"
|
||||
if [ x"$venv" = x ]; then
|
||||
export venv="`which virtualenv`"
|
||||
#export spec="-p 2.7"
|
||||
export spec="-p 2.7"
|
||||
fi
|
||||
|
@ -22,8 +22,8 @@ except ImportError:
|
||||
###########
|
||||
# Constants
|
||||
|
||||
CURRENT_I2P_VERSION = '2.9.0'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.9.0'
|
||||
CURRENT_I2P_VERSION = '2.3.0'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.3.0'
|
||||
CURRENT_I2P_OSX_VERSION = '1.9.0'
|
||||
|
||||
CANONICAL_DOMAIN = 'geti2p.net'
|
||||
@ -67,32 +67,32 @@ SUPPORTED_LANGS = [
|
||||
]
|
||||
|
||||
SUPPORTED_LANG_NAMES = {
|
||||
'ar': u'Arabic العربية',
|
||||
'id': u'Bahasa Indonesia',
|
||||
'zh': u'Chinese 中文',
|
||||
'zh_TW': u'Chinese 中文 (繁體中文, 台灣)',
|
||||
'de': u'Deutsch',
|
||||
'en': u'English',
|
||||
'es': u'Castellano',
|
||||
'fr': u'Français',
|
||||
'el': u'Greek Ελληνικά',
|
||||
'he': u'Hebrew עברית',
|
||||
'hu': u'Hungarian',
|
||||
'it': u'Italiano',
|
||||
'ja': u'Japanese 日本語',
|
||||
'ko': u'Korean 한국말',
|
||||
'mg': u'Fiteny Malagasy',
|
||||
'nl': u'Nederlands',
|
||||
'fa': u'Persian فارسی',
|
||||
'pl': u'Polski',
|
||||
'pt': u'Português',
|
||||
'pt_BR': u'Português do Brasil',
|
||||
'ro': u'Română',
|
||||
'ru': u'Russian Русский язык',
|
||||
'fi': u'Suomi',
|
||||
'sv': u'Svenska',
|
||||
'tr': u'Türkçe',
|
||||
'uk': u'Ukrainian Українська',
|
||||
'ar': 'Arabic العربية',
|
||||
'id': 'Bahasa Indonesia',
|
||||
'zh': 'Chinese 中文',
|
||||
'zh_TW': 'Chinese 中文 (繁體中文, 台灣)',
|
||||
'de': 'Deutsch',
|
||||
'en': 'English',
|
||||
'es': 'Castellano',
|
||||
'fr': 'Français',
|
||||
'el': 'Greek Ελληνικά',
|
||||
'he': 'Hebrew עברית',
|
||||
'hu': 'Hungarian',
|
||||
'it': 'Italiano',
|
||||
'ja': 'Japanese 日本語',
|
||||
'ko': 'Korean 한국말',
|
||||
'mg': 'Fiteny Malagasy',
|
||||
'nl': 'Nederlands',
|
||||
'fa': 'Persian فارسی',
|
||||
'pl': 'Polski',
|
||||
'pt': 'Português',
|
||||
'pt_BR': 'Português do Brasil',
|
||||
'ro': 'Română',
|
||||
'ru': 'Russian Русский язык',
|
||||
'fi': 'Suomi',
|
||||
'sv': 'Svenska',
|
||||
'tr': 'Türkçe',
|
||||
'uk': 'Ukrainian Українська',
|
||||
}
|
||||
|
||||
RTL_LANGS = [
|
||||
@ -213,7 +213,7 @@ def detect_theme():
|
||||
theme = 'duck'
|
||||
if 'style' in request.cookies:
|
||||
theme = request.cookies['style']
|
||||
if 'theme' in request.args.keys():
|
||||
if 'theme' in list(request.args.keys()):
|
||||
theme = request.args['theme']
|
||||
# TEMPORARY: enable external themes
|
||||
# TODO: Remove this (and the corresponding lines in global/layout.html
|
||||
@ -263,5 +263,5 @@ def server_error(error):
|
||||
return render_template('global/error_500.html'), 500
|
||||
|
||||
# Import these to ensure they get loaded
|
||||
import templatevars
|
||||
import urls
|
||||
from . import templatevars
|
||||
from . import urls
|
||||
|
@ -6,14 +6,14 @@
|
||||
Based on perl code by Eddie Kohler; heavily modified.
|
||||
"""
|
||||
|
||||
import cStringIO
|
||||
import io
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
|
||||
import config
|
||||
from . import config
|
||||
|
||||
import rank
|
||||
from . import rank
|
||||
|
||||
__all__ = [ 'ParseError', 'BibTeX', 'BibTeXEntry', 'htmlize',
|
||||
'ParsedAuthor', 'FileIter', 'Parser', 'parseFile',
|
||||
@ -66,7 +66,7 @@ class BibTeX:
|
||||
"""Add a BibTeX entry to this file."""
|
||||
k = ent.key
|
||||
if self.byKey.get(ent.key.lower()):
|
||||
print >> sys.stderr, "Already have an entry named %s"%k
|
||||
print("Already have an entry named %s"%k, file=sys.stderr)
|
||||
return
|
||||
self.entries.append(ent)
|
||||
self.byKey[ent.key.lower()] = ent
|
||||
@ -79,7 +79,7 @@ class BibTeX:
|
||||
try:
|
||||
cr = self.byKey[ent['crossref'].lower()]
|
||||
except KeyError:
|
||||
print "No such crossref: %s"% ent['crossref']
|
||||
print("No such crossref: %s"% ent['crossref'])
|
||||
break
|
||||
if seen.get(cr.key):
|
||||
raise ParseError("Circular crossref at %s" % ent.key)
|
||||
@ -87,12 +87,12 @@ class BibTeX:
|
||||
del ent.entries['crossref']
|
||||
|
||||
if cr.entryLine < ent.entryLine:
|
||||
print "Warning: crossref %s used after declaration"%cr.key
|
||||
print("Warning: crossref %s used after declaration"%cr.key)
|
||||
|
||||
for k in cr.entries.keys():
|
||||
if ent.entries.has_key(k):
|
||||
print "ERROR: %s defined both in %s and in %s"%(
|
||||
k,ent.key,cr.key)
|
||||
for k in list(cr.entries.keys()):
|
||||
if k in ent.entries:
|
||||
print("ERROR: %s defined both in %s and in %s"%(
|
||||
k,ent.key,cr.key))
|
||||
else:
|
||||
ent.entries[k] = cr.entries[k]
|
||||
|
||||
@ -105,7 +105,7 @@ class BibTeX:
|
||||
rk = "title"
|
||||
|
||||
for ent in self.entries:
|
||||
if ent.type in config.OMIT_ENTRIES or not ent.has_key(rk):
|
||||
if ent.type in config.OMIT_ENTRIES or rk not in ent:
|
||||
ent.check()
|
||||
del self.byKey[ent.key.lower()]
|
||||
else:
|
||||
@ -122,7 +122,7 @@ def buildAuthorTable(entries):
|
||||
authorsByLast.setdefault(tuple(a.last), []).append(a)
|
||||
# map from author to collapsed author.
|
||||
result = {}
|
||||
for k,v in config.COLLAPSE_AUTHORS.items():
|
||||
for k,v in list(config.COLLAPSE_AUTHORS.items()):
|
||||
a = parseAuthor(k)[0]
|
||||
c = parseAuthor(v)[0]
|
||||
result[c] = c
|
||||
@ -130,7 +130,7 @@ def buildAuthorTable(entries):
|
||||
|
||||
for e in entries:
|
||||
for author in e.parsedAuthor:
|
||||
if result.has_key(author):
|
||||
if author in result:
|
||||
continue
|
||||
|
||||
c = author
|
||||
@ -141,16 +141,16 @@ def buildAuthorTable(entries):
|
||||
result[author] = c
|
||||
|
||||
if 0:
|
||||
for a,c in result.items():
|
||||
for a,c in list(result.items()):
|
||||
if a != c:
|
||||
print "Collapsing authors: %s => %s" % (a,c)
|
||||
print("Collapsing authors: %s => %s" % (a,c))
|
||||
if 0:
|
||||
print parseAuthor("Franz Kaashoek")[0].collapsesTo(
|
||||
parseAuthor("M. Franz Kaashoek")[0])
|
||||
print parseAuthor("Paul F. Syverson")[0].collapsesTo(
|
||||
parseAuthor("Paul Syverson")[0])
|
||||
print parseAuthor("Paul Syverson")[0].collapsesTo(
|
||||
parseAuthor("Paul F. Syverson")[0])
|
||||
print(parseAuthor("Franz Kaashoek")[0].collapsesTo(
|
||||
parseAuthor("M. Franz Kaashoek")[0]))
|
||||
print(parseAuthor("Paul F. Syverson")[0].collapsesTo(
|
||||
parseAuthor("Paul Syverson")[0]))
|
||||
print(parseAuthor("Paul Syverson")[0].collapsesTo(
|
||||
parseAuthor("Paul F. Syverson")[0]))
|
||||
|
||||
return result
|
||||
|
||||
@ -221,7 +221,7 @@ def splitEntriesByAuthor(entries):
|
||||
|
||||
htmlResult[sortkey] = secname
|
||||
result.setdefault(sortkey, []).append(ent)
|
||||
sortnames = result.keys()
|
||||
sortnames = list(result.keys())
|
||||
sortnames.sort()
|
||||
sections = [ (htmlResult[n], result[n]) for n in sortnames ]
|
||||
return sections, url_map
|
||||
@ -255,13 +255,13 @@ def sortEntriesByDate(entries):
|
||||
monthname = match.group(1)
|
||||
mon = MONTHS.index(monthname)
|
||||
except ValueError:
|
||||
print "Unknown month %r in %s"%(ent.get("month"), ent.key)
|
||||
print("Unknown month %r in %s"%(ent.get("month"), ent.key))
|
||||
mon = 0
|
||||
|
||||
try:
|
||||
date = int(ent['year'])*13 + mon
|
||||
except KeyError:
|
||||
print "ERROR: No year field in %s"%ent.key
|
||||
print("ERROR: No year field in %s"%ent.key)
|
||||
date = 10000*13
|
||||
except ValueError:
|
||||
date = 10000*13
|
||||
@ -286,7 +286,7 @@ class BibTeXEntry:
|
||||
def get(self, k, v=None):
|
||||
return self.entries.get(k,v)
|
||||
def has_key(self, k):
|
||||
return self.entries.has_key(k)
|
||||
return k in self.entries
|
||||
def __getitem__(self, k):
|
||||
return self.entries[k]
|
||||
def __setitem__(self, k, v):
|
||||
@ -312,13 +312,13 @@ class BibTeXEntry:
|
||||
d = ["@%s{%s,\n" % (self.type, self.key)]
|
||||
if v:
|
||||
df = DISPLAYED_FIELDS[:]
|
||||
for k in self.entries.keys():
|
||||
for k in list(self.entries.keys()):
|
||||
if k not in df:
|
||||
df.append(k)
|
||||
else:
|
||||
df = DISPLAYED_FIELDS
|
||||
for f in df:
|
||||
if not self.entries.has_key(f):
|
||||
if f not in self.entries:
|
||||
continue
|
||||
v = self.entries[f]
|
||||
if v.startswith("<span class='bad'>"):
|
||||
@ -330,7 +330,7 @@ class BibTeXEntry:
|
||||
d.append("%%%%% "+("ERROR: Non-ASCII characters: '%r'\n"%np))
|
||||
d.append(" ")
|
||||
v = v.replace("&", "&")
|
||||
if invStrings.has_key(v):
|
||||
if v in invStrings:
|
||||
s = "%s = %s,\n" %(f, invStrings[v])
|
||||
else:
|
||||
s = "%s = {%s},\n" % (f, v)
|
||||
@ -359,7 +359,7 @@ class BibTeXEntry:
|
||||
none."""
|
||||
errs = self._check()
|
||||
for e in errs:
|
||||
print e
|
||||
print(e)
|
||||
return not errs
|
||||
|
||||
def _check(self):
|
||||
@ -396,14 +396,14 @@ class BibTeXEntry:
|
||||
not self['booktitle'].startswith("{Proceedings of"):
|
||||
errs.append("ERROR: %s's booktitle (%r) doesn't start with 'Proceedings of'" % (self.key, self['booktitle']))
|
||||
|
||||
if self.has_key("pages") and not re.search(r'\d+--\d+', self['pages']):
|
||||
if "pages" in self and not re.search(r'\d+--\d+', self['pages']):
|
||||
errs.append("ERROR: Misformed pages in %s"%self.key)
|
||||
|
||||
if self.type == 'proceedings':
|
||||
if self.get('title'):
|
||||
errs.append("ERROR: %s is a proceedings: it should have a booktitle, not a title." % self.key)
|
||||
|
||||
for field, value in self.entries.items():
|
||||
for field, value in list(self.entries.items()):
|
||||
if value.translate(ALLCHARS, PRINTINGCHARS):
|
||||
errs.append("ERROR: %s.%s has non-ASCII characters"%(
|
||||
self.key, field))
|
||||
@ -551,8 +551,8 @@ class BibTeXEntry:
|
||||
cache_section = self.get('www_cache_section', ".")
|
||||
if cache_section not in config.CACHE_SECTIONS:
|
||||
if cache_section != ".":
|
||||
print >>sys.stderr, "Unrecognized cache section %s"%(
|
||||
cache_section)
|
||||
print("Unrecognized cache section %s"%(
|
||||
cache_section), file=sys.stderr)
|
||||
cache_section="."
|
||||
|
||||
for key, name, ext in (('www_abstract_url', 'abstract','abstract'),
|
||||
@ -766,13 +766,13 @@ class ParsedAuthor:
|
||||
short = o.first; long = self.first
|
||||
|
||||
initials_s = "".join([n[0] for n in short])
|
||||
initials_l = "".join([n[0] for n in long])
|
||||
initials_l = "".join([n[0] for n in int])
|
||||
idx = initials_l.find(initials_s)
|
||||
if idx < 0:
|
||||
return self
|
||||
n = long[:idx]
|
||||
n = int[:idx]
|
||||
for i in range(idx, idx+len(short)):
|
||||
a = long[i]; b = short[i-idx]
|
||||
a = int[i]; b = short[i-idx]
|
||||
if a == b:
|
||||
n.append(a)
|
||||
elif len(a) == 2 and a[1] == '.' and a[0] == b[0]:
|
||||
@ -781,7 +781,7 @@ class ParsedAuthor:
|
||||
n.append(a)
|
||||
else:
|
||||
return self
|
||||
n += long[idx+len(short):]
|
||||
n += int[idx+len(short):]
|
||||
|
||||
if n == self.first:
|
||||
return self
|
||||
@ -842,7 +842,7 @@ def _split(s,w=79,indent=8):
|
||||
first = 1
|
||||
indentation = ""
|
||||
while len(s) > w:
|
||||
for i in xrange(w-1, 20, -1):
|
||||
for i in range(w-1, 20, -1):
|
||||
if s[i] == ' ':
|
||||
r.append(indentation+s[:i])
|
||||
s = s[i+1:]
|
||||
@ -864,14 +864,14 @@ class FileIter:
|
||||
if fname:
|
||||
file = open(fname, 'r')
|
||||
if string:
|
||||
file = cStringIO.StringIO(string)
|
||||
file = io.StringIO(string)
|
||||
if file:
|
||||
it = iter(file.xreadlines())
|
||||
it = iter(file)
|
||||
self.iter = it
|
||||
assert self.iter
|
||||
self.lineno = 0
|
||||
self._next = it.next
|
||||
def next(self):
|
||||
self._next = it.__next__
|
||||
def __next__(self):
|
||||
self.lineno += 1
|
||||
return self._next()
|
||||
|
||||
@ -880,7 +880,7 @@ def parseAuthor(s):
|
||||
try:
|
||||
return _parseAuthor(s)
|
||||
except:
|
||||
print >>sys.stderr, "Internal error while parsing author %r"%s
|
||||
print("Internal error while parsing author %r"%s, file=sys.stderr)
|
||||
raise
|
||||
|
||||
def _parseAuthor(s):
|
||||
@ -891,7 +891,7 @@ def _parseAuthor(s):
|
||||
while s:
|
||||
s = s.strip()
|
||||
bracelevel = 0
|
||||
for i in xrange(len(s)):
|
||||
for i in range(len(s)):
|
||||
if s[i] == '{':
|
||||
bracelevel += 1
|
||||
elif s[i] == '}':
|
||||
@ -947,8 +947,8 @@ def _parseAuthor(s):
|
||||
|
||||
return parsedAuthors
|
||||
|
||||
ALLCHARS = "".join(map(chr,range(256)))
|
||||
PRINTINGCHARS = "\t\n\r"+"".join(map(chr,range(32, 127)))
|
||||
ALLCHARS = "".join(map(chr,list(range(256))))
|
||||
PRINTINGCHARS = "\t\n\r"+"".join(map(chr,list(range(32, 127))))
|
||||
LC_CHARS = "abcdefghijklmnopqrstuvwxyz"
|
||||
SV_DELCHARS = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
@ -995,7 +995,7 @@ class Parser:
|
||||
self.strings.update(initial_strings)
|
||||
self.newStrings = {}
|
||||
self.invStrings = {}
|
||||
for k,v in config.INITIAL_STRINGS.items():
|
||||
for k,v in list(config.INITIAL_STRINGS.items()):
|
||||
self.invStrings[v]=k
|
||||
self.fileiter = fileiter
|
||||
if result is None:
|
||||
@ -1049,7 +1049,7 @@ class Parser:
|
||||
continue
|
||||
data.append(line)
|
||||
data.append(" ")
|
||||
line = it.next()
|
||||
line = next(it)
|
||||
self.litStringLine = 0
|
||||
elif line[0] == '{':
|
||||
bracelevel += 1
|
||||
@ -1076,13 +1076,13 @@ class Parser:
|
||||
#print bracelevel, "C", repr(line)
|
||||
data.append(line)
|
||||
data.append(" ")
|
||||
line = it.next()
|
||||
line = next(it)
|
||||
elif line[0] == '#':
|
||||
print >>sys.stderr, "Weird concat on line %s"%it.lineno
|
||||
print("Weird concat on line %s"%it.lineno, file=sys.stderr)
|
||||
elif line[0] in "},":
|
||||
if not data:
|
||||
print >>sys.stderr, "No data after field on line %s"%(
|
||||
it.lineno)
|
||||
print("No data after field on line %s"%(
|
||||
it.lineno), file=sys.stderr)
|
||||
else:
|
||||
m = RAW_DATA_RE.match(line)
|
||||
if m:
|
||||
@ -1170,7 +1170,7 @@ class Parser:
|
||||
else:
|
||||
key = v[0]
|
||||
d = {}
|
||||
for i in xrange(1,len(v),2):
|
||||
for i in range(1,len(v),2):
|
||||
d[v[i].lower()] = v[i+1]
|
||||
ent = BibTeXEntry(self.curEntType, key, d)
|
||||
ent.entryLine = self.entryLine
|
||||
@ -1197,11 +1197,11 @@ class Parser:
|
||||
|
||||
def _parse(self):
|
||||
it = self.fileiter
|
||||
line = it.next()
|
||||
line = next(it)
|
||||
while 1:
|
||||
# Skip blank lines.
|
||||
while not line or line.isspace() or OUTER_COMMENT_RE.match(line):
|
||||
line = it.next()
|
||||
line = next(it)
|
||||
# Get the first line of an entry.
|
||||
m = ENTRY_BEGIN_RE.match(line)
|
||||
if m:
|
||||
@ -1215,7 +1215,7 @@ class Parser:
|
||||
|
||||
def _advance(it,line):
|
||||
while not line or line.isspace() or COMMENT_RE.match(line):
|
||||
line = it.next()
|
||||
line = next(it)
|
||||
return line
|
||||
|
||||
# Matches a comment line outside of an entry.
|
||||
@ -1265,5 +1265,5 @@ if __name__ == '__main__':
|
||||
|
||||
for e in r.entries:
|
||||
if e.type in ("proceedings", "journal"): continue
|
||||
print e.to_html()
|
||||
print(e.to_html())
|
||||
|
||||
|
@ -19,7 +19,7 @@ del _k
|
||||
|
||||
def load(cfgFile):
|
||||
mod = {}
|
||||
execfile(cfgFile, mod)
|
||||
exec(compile(open(cfgFile, "rb").read(), cfgFile, 'exec'), mod)
|
||||
for _k in _KEYS:
|
||||
try:
|
||||
globals()[_k]=mod[_k]
|
||||
@ -28,7 +28,7 @@ def load(cfgFile):
|
||||
|
||||
INITIAL_STRINGS.update(_EXTRA_INITIAL_STRINGS)
|
||||
AUTHOR_RE_LIST[:] = [
|
||||
(re.compile(k, re.I), v,) for k, v in AUTHOR_URLS.items()
|
||||
(re.compile(k, re.I), v,) for k, v in list(AUTHOR_URLS.items())
|
||||
]
|
||||
|
||||
NO_COLLAPSE_AUTHORS_RE_LIST[:] = [
|
||||
@ -36,7 +36,7 @@ def load(cfgFile):
|
||||
]
|
||||
|
||||
ALPHABETIZE_AUTHOR_AS_RE_LIST[:] = [
|
||||
(re.compile(k, re.I), v,) for k,v in ALPHABETIZE_AUTHOR_AS.items()
|
||||
(re.compile(k, re.I), v,) for k,v in list(ALPHABETIZE_AUTHOR_AS.items())
|
||||
]
|
||||
|
||||
_EXTRA_INITIAL_STRINGS = {
|
||||
|
@ -45,7 +45,7 @@ SINGLETONS = {
|
||||
'z': 's',
|
||||
}
|
||||
|
||||
ALLCHARS = "".join(map(chr, range(256)))
|
||||
ALLCHARS = "".join(map(chr, list(range(256))))
|
||||
NONLCCHARS = "".join([c for c in ALLCHARS if not c.islower()])
|
||||
def metaphone(s):
|
||||
"""Return the metaphone equivalent of a provided string"""
|
||||
@ -182,7 +182,7 @@ def metaphone(s):
|
||||
return "".join(result)
|
||||
|
||||
def demo(a):
|
||||
print a, "=>", metaphone(a)
|
||||
print(a, "=>", metaphone(a))
|
||||
|
||||
if __name__ == '__main__':
|
||||
demo("Nick. Mathewson")
|
||||
|
@ -7,7 +7,7 @@
|
||||
cache_expire = 60*60*24*30 # 30 days
|
||||
|
||||
# Checks
|
||||
import config
|
||||
from . import config
|
||||
import os
|
||||
import sys
|
||||
from os.path import exists, isdir, join, getmtime
|
||||
@ -32,8 +32,8 @@ def cache_folder():
|
||||
return r
|
||||
|
||||
import re
|
||||
from urllib2 import urlopen, build_opener
|
||||
from urllib import quote
|
||||
from urllib.request import urlopen, build_opener
|
||||
from urllib.parse import quote
|
||||
from datetime import date
|
||||
import hashlib
|
||||
|
||||
@ -66,17 +66,17 @@ def getPageForTitle(title, cache=True, update=True, save=True):
|
||||
if exists(join(cache_folder(), md5h(url))) and cache:
|
||||
return url, file(join(cache_folder(), md5h(url)),'r').read()
|
||||
elif update:
|
||||
print "Downloading rank for %r."%title
|
||||
print("Downloading rank for %r."%title)
|
||||
|
||||
# Make a custom user agent (so that we are not filtered by Google)!
|
||||
opener = build_opener()
|
||||
opener.addheaders = [('User-agent', 'Anon.Bib.0.1')]
|
||||
|
||||
print "connecting..."
|
||||
print("connecting...")
|
||||
connection = opener.open(url)
|
||||
print "reading"
|
||||
print("reading")
|
||||
page = connection.read()
|
||||
print "done"
|
||||
print("done")
|
||||
if save:
|
||||
file(join(cache_folder(), md5h(url)),'w').write(page)
|
||||
return url, page
|
||||
@ -140,20 +140,20 @@ def get_rank_html(title, years=None, base_url=".", update=True,
|
||||
def TestScholarFormat():
|
||||
# We need to ensure that Google Scholar does not change its page format under our feet
|
||||
# Use some cases to check if all is good
|
||||
print "Checking google scholar formats..."
|
||||
print("Checking google scholar formats...")
|
||||
stopAndGoCites = getCite("Stop-and-Go MIXes: Providing Probabilistic Anonymity in an Open System", False)[0]
|
||||
dragonCites = getCite("Mixes protected by Dragons and Pixies: an empirical study", False, save=False)[0]
|
||||
|
||||
if stopAndGoCites in (0, None):
|
||||
print """OOPS.\n
|
||||
print("""OOPS.\n
|
||||
It looks like Google Scholar changed their URL format or their output format.
|
||||
I went to count the cites for the Stop-and-Go MIXes paper, and got nothing."""
|
||||
I went to count the cites for the Stop-and-Go MIXes paper, and got nothing.""")
|
||||
sys.exit(1)
|
||||
|
||||
if dragonCites != None:
|
||||
print """OOPS.\n
|
||||
print("""OOPS.\n
|
||||
It looks like Google Scholar changed their URL format or their output format.
|
||||
I went to count the cites for a fictitious paper, and found some."""
|
||||
I went to count the cites for a fictitious paper, and found some.""")
|
||||
sys.exit(1)
|
||||
|
||||
def urlIsUseless(u):
|
||||
@ -170,7 +170,7 @@ URLTYPES=[ "pdf", "ps", "txt", "ps_gz", "html" ]
|
||||
|
||||
if __name__ == '__main__':
|
||||
# First download the bibliography file.
|
||||
import BibTeX
|
||||
from . import BibTeX
|
||||
suggest = False
|
||||
if sys.argv[1] == 'suggest':
|
||||
suggest = True
|
||||
@ -182,7 +182,7 @@ if __name__ == '__main__':
|
||||
bib = BibTeX.parseFile(config.MASTER_BIB)
|
||||
remove_old()
|
||||
|
||||
print "Downloading missing ranks."
|
||||
print("Downloading missing ranks.")
|
||||
for ent in bib.entries:
|
||||
getCite(ent['title'], cache=True, update=True)
|
||||
|
||||
@ -190,13 +190,13 @@ if __name__ == '__main__':
|
||||
for ent in bib.entries:
|
||||
haveOne = False
|
||||
for utype in URLTYPES:
|
||||
if ent.has_key("www_%s_url"%utype):
|
||||
if "www_%s_url"%utype in ent:
|
||||
haveOne = True
|
||||
break
|
||||
if haveOne:
|
||||
continue
|
||||
print ent.key, "has no URLs given."
|
||||
print(ent.key, "has no URLs given.")
|
||||
urls = [ u for u in getPaperURLs(ent['title']) if not urlIsUseless(u) ]
|
||||
for u in urls:
|
||||
print "\t", u
|
||||
print("\t", u)
|
||||
|
||||
|
@ -13,9 +13,9 @@ import re
|
||||
|
||||
assert sys.version_info[:3] >= (2,2,0)
|
||||
|
||||
import BibTeX
|
||||
import config
|
||||
import metaphone
|
||||
from . import BibTeX
|
||||
from . import config
|
||||
from . import metaphone
|
||||
|
||||
_MPCACHE = {}
|
||||
def soundsLike(s1, s2):
|
||||
@ -168,16 +168,16 @@ class MasterBibTeX(BibTeX.BibTeX):
|
||||
matches = m2
|
||||
|
||||
if not matches:
|
||||
print "No match for %s"%e.key
|
||||
print("No match for %s"%e.key)
|
||||
if matches[-1][1] is e:
|
||||
print "%s matches for %s: OK."%(len(matches), e.key)
|
||||
print("%s matches for %s: OK."%(len(matches), e.key))
|
||||
else:
|
||||
print "%s matches for %s: %s is best!" %(len(matches), e.key,
|
||||
matches[-1][1].key)
|
||||
print("%s matches for %s: %s is best!" %(len(matches), e.key,
|
||||
matches[-1][1].key))
|
||||
if len(matches) > 1:
|
||||
for g, m in matches:
|
||||
print "%%%% goodness", g
|
||||
print m
|
||||
print("%%%% goodness", g)
|
||||
print(m)
|
||||
|
||||
|
||||
def noteToURL(note):
|
||||
@ -202,7 +202,7 @@ def emit(f,ent):
|
||||
global all_ok
|
||||
|
||||
errs = ent._check()
|
||||
if master.byKey.has_key(ent.key.strip().lower()):
|
||||
if ent.key.strip().lower() in master.byKey:
|
||||
errs.append("ERROR: Key collision with master file")
|
||||
|
||||
if errs:
|
||||
@ -210,7 +210,7 @@ def emit(f,ent):
|
||||
|
||||
note = ent.get("note")
|
||||
if ent.getURL() and not note:
|
||||
ent['note'] = "\url{%s}"%ent.getURL()
|
||||
ent['note'] = "\\url{%s}"%ent.getURL()
|
||||
elif note:
|
||||
m = re.match(r'\\url{(.*)}', note)
|
||||
if m:
|
||||
@ -232,61 +232,61 @@ def emit(f,ent):
|
||||
if errs:
|
||||
all_ok = 0
|
||||
for e in errs:
|
||||
print >>f, "%%%%", e
|
||||
print("%%%%", e, file=f)
|
||||
|
||||
print >>f, ent.format(77, 4, v=1, invStrings=invStrings)
|
||||
print(ent.format(77, 4, v=1, invStrings=invStrings), file=f)
|
||||
|
||||
def emitKnown(f, ent, matches):
|
||||
print >>f, "%% Candidates are:", ", ".join([e.key for g,e in matches])
|
||||
print >>f, "%%"
|
||||
print >>f, "%"+(ent.format(77,4,1,invStrings).replace("\n", "\n%"))
|
||||
print("%% Candidates are:", ", ".join([e.key for g,e in matches]), file=f)
|
||||
print("%%", file=f)
|
||||
print("%"+(ent.format(77,4,1,invStrings).replace("\n", "\n%")), file=f)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print "reconcile.py expects 2 arguments"
|
||||
print("reconcile.py expects 2 arguments")
|
||||
sys.exit(1)
|
||||
|
||||
config.load(sys.argv[1])
|
||||
|
||||
print "========= Scanning master =========="
|
||||
print("========= Scanning master ==========")
|
||||
master = MasterBibTeX()
|
||||
master = BibTeX.parseFile(config.MASTER_BIB, result=master)
|
||||
master.buildIndex()
|
||||
|
||||
print "========= Scanning new file ========"
|
||||
print("========= Scanning new file ========")
|
||||
try:
|
||||
fn = sys.argv[2]
|
||||
input = BibTeX.parseFile(fn)
|
||||
except BibTeX.ParseError, e:
|
||||
print "Error parsing %s: %s"%(fn,e)
|
||||
except BibTeX.ParseError as e:
|
||||
print("Error parsing %s: %s"%(fn,e))
|
||||
sys.exit(1)
|
||||
|
||||
f = open('tmp.bib', 'w')
|
||||
keys = input.newStrings.keys()
|
||||
keys = list(input.newStrings.keys())
|
||||
keys.sort()
|
||||
for k in keys:
|
||||
v = input.newStrings[k]
|
||||
print >>f, "@string{%s = {%s}}"%(k,v)
|
||||
print("@string{%s = {%s}}"%(k,v), file=f)
|
||||
|
||||
invStrings = input.invStrings
|
||||
|
||||
for e in input.entries:
|
||||
if not (e.get('title') and e.get('author')):
|
||||
print >>f, "%%\n%%%% Not enough information to search for a match: need title and author.\n%%"
|
||||
print("%%\n%%%% Not enough information to search for a match: need title and author.\n%%", file=f)
|
||||
emit(f, e)
|
||||
continue
|
||||
|
||||
matches = master.includes(e, all=1)
|
||||
if not matches:
|
||||
print >>f, "%%\n%%%% This entry is probably new: No match found.\n%%"
|
||||
print("%%\n%%%% This entry is probably new: No match found.\n%%", file=f)
|
||||
emit(f, e)
|
||||
else:
|
||||
print >>f, "%%"
|
||||
print >>f, "%%%% Possible match found for this entry; max goodness",\
|
||||
matches[-1][0], "\n%%"
|
||||
print("%%", file=f)
|
||||
print("%%%% Possible match found for this entry; max goodness",\
|
||||
matches[-1][0], "\n%%", file=f)
|
||||
emitKnown(f, e, matches)
|
||||
|
||||
if not all_ok:
|
||||
print >>f, "\n\n\nErrors remain; not finished.\n"
|
||||
print("\n\n\nErrors remain; not finished.\n", file=f)
|
||||
|
||||
f.close()
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
"""Unit tests for anonbib."""
|
||||
|
||||
import BibTeX
|
||||
import metaphone
|
||||
from . import BibTeX
|
||||
from . import metaphone
|
||||
#import reconcile
|
||||
#import writeHTML
|
||||
#import updateCache
|
||||
@ -18,40 +18,40 @@ class MetaphoneTests(unittest.TestCase):
|
||||
class BibTeXTests(unittest.TestCase):
|
||||
def testTranslation(self):
|
||||
ut = BibTeX.url_untranslate
|
||||
self.assertEquals(ut("Fred"),"Fred")
|
||||
self.assertEquals(ut("Hello, World."), "Hello_2c_20World.")
|
||||
self.assertEqual(ut("Fred"),"Fred")
|
||||
self.assertEqual(ut("Hello, World."), "Hello_2c_20World.")
|
||||
|
||||
te = BibTeX.TeXescapeURL
|
||||
ute = BibTeX.unTeXescapeURL
|
||||
self.assertEquals(te("http://example/~me/my_file"),
|
||||
self.assertEqual(te("http://example/~me/my_file"),
|
||||
r"http://example/\{}~me/my\_file")
|
||||
self.assertEquals(ute(r"http:{}//example/\{}~me/my\_file"),
|
||||
self.assertEqual(ute(r"http:{}//example/\{}~me/my\_file"),
|
||||
"http://example/~me/my_file")
|
||||
|
||||
h = BibTeX.htmlize
|
||||
self.assertEquals(h("Hello, world"), "Hello, world")
|
||||
self.assertEquals(h(r"\'a\`e\'{i}(\'\i)\"o&\^u"),
|
||||
self.assertEqual(h("Hello, world"), "Hello, world")
|
||||
self.assertEqual(h(r"\'a\`e\'{i}(\'\i)\"o&\^u"),
|
||||
"áèí(í)ö&"
|
||||
"û")
|
||||
self.assertEquals(h(r"\~n and \c{c}"), "ñ and ç")
|
||||
self.assertEquals(h(r"\AE---a ligature"), "Æ—a ligature")
|
||||
self.assertEquals(h(r"{\it 33}"), " 33")
|
||||
self.assertEquals(h(r"Pages 33--99 or vice--versa?"),
|
||||
self.assertEqual(h(r"\~n and \c{c}"), "ñ and ç")
|
||||
self.assertEqual(h(r"\AE---a ligature"), "Æ—a ligature")
|
||||
self.assertEqual(h(r"{\it 33}"), " 33")
|
||||
self.assertEqual(h(r"Pages 33--99 or vice--versa?"),
|
||||
"Pages 33-99 or vice–versa?")
|
||||
|
||||
t = BibTeX.txtize
|
||||
self.assertEquals(t("Hello, world"), "Hello, world")
|
||||
self.assertEquals(t(r"\'a\`e\'{i}(\'\i)\"o&\^u"),
|
||||
self.assertEqual(t("Hello, world"), "Hello, world")
|
||||
self.assertEqual(t(r"\'a\`e\'{i}(\'\i)\"o&\^u"),
|
||||
"aei(i)o&u")
|
||||
self.assertEquals(t(r"\~n and \c{c}"), "n and c")
|
||||
self.assertEquals(t(r"\AE---a ligature"), "AE---a ligature")
|
||||
self.assertEquals(t(r"{\it 33}"), " 33")
|
||||
self.assertEquals(t(r"Pages 33--99 or vice--versa?"),
|
||||
self.assertEqual(t(r"\~n and \c{c}"), "n and c")
|
||||
self.assertEqual(t(r"\AE---a ligature"), "AE---a ligature")
|
||||
self.assertEqual(t(r"{\it 33}"), " 33")
|
||||
self.assertEqual(t(r"Pages 33--99 or vice--versa?"),
|
||||
"Pages 33--99 or vice--versa?")
|
||||
|
||||
def authorsParseTo(self,authors,result):
|
||||
pa = BibTeX.parseAuthor(authors)
|
||||
self.assertEquals(["|".join(["+".join(item) for item in
|
||||
self.assertEqual(["|".join(["+".join(item) for item in
|
||||
[a.first,a.von,a.last,a.jr]])
|
||||
for a in pa],
|
||||
result)
|
||||
|
@ -10,13 +10,13 @@ import signal
|
||||
import time
|
||||
import gzip
|
||||
|
||||
import BibTeX
|
||||
import config
|
||||
import urllib2
|
||||
from . import BibTeX
|
||||
from . import config
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
import getopt
|
||||
import socket
|
||||
import errno
|
||||
import httplib
|
||||
import http.client
|
||||
|
||||
FILE_TYPES = [ "txt", "html", "pdf", "ps", "ps.gz", "abstract" ]
|
||||
BIN_FILE_TYPES = [ 'pdf', 'ps.gz' ]
|
||||
@ -53,12 +53,12 @@ def downloadFile(key, ftype, section, url,timeout=None):
|
||||
signal.alarm(timeout)
|
||||
try:
|
||||
try:
|
||||
infile = urllib2.urlopen(url)
|
||||
except httplib.InvalidURL, e:
|
||||
infile = urllib.request.urlopen(url)
|
||||
except http.client.InvalidURL as e:
|
||||
raise UIError("Invalid URL %s: %s"%(url,e))
|
||||
except IOError, e:
|
||||
except IOError as e:
|
||||
raise UIError("Cannot connect to url %s: %s"%(url,e))
|
||||
except socket.error, e:
|
||||
except socket.error as e:
|
||||
if getattr(e,"errno",-1) == errno.EINTR:
|
||||
raise UIError("Connection timed out to url %s"%url)
|
||||
else:
|
||||
@ -80,9 +80,9 @@ def downloadFile(key, ftype, section, url,timeout=None):
|
||||
outfile.close()
|
||||
|
||||
urlfile = open(fnameURL, 'w')
|
||||
print >>urlfile, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), file=urlfile)
|
||||
if "\n" in url: url = url.replace("\n", " ")
|
||||
print >>urlfile, url
|
||||
print(url, file=urlfile)
|
||||
urlfile.close()
|
||||
|
||||
os.rename(fnameTmp, fname)
|
||||
@ -105,7 +105,7 @@ def getCachedURL(key, ftype, section):
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
if len(lines) != 2:
|
||||
print >>sys.stderr, "ERROR: unexpected number of lines in", urlFname
|
||||
print("ERROR: unexpected number of lines in", urlFname, file=sys.stderr)
|
||||
return lines[1].strip()
|
||||
|
||||
def downloadAll(bibtex, missingOnly=0):
|
||||
@ -115,33 +115,33 @@ def downloadAll(bibtex, missingOnly=0):
|
||||
urls = getURLs(e)
|
||||
key = e.key
|
||||
section = e.get("www_cache_section", ".")
|
||||
for ftype, url in urls.items():
|
||||
for ftype, url in list(urls.items()):
|
||||
if missingOnly:
|
||||
cachedURL = getCachedURL(key, ftype, section)
|
||||
if cachedURL == url:
|
||||
print >>sys.stderr,"Skipping",url
|
||||
print("Skipping",url, file=sys.stderr)
|
||||
continue
|
||||
elif cachedURL is not None:
|
||||
print >>sys.stderr,"URL for %s.%s has changed"%(key,ftype)
|
||||
print("URL for %s.%s has changed"%(key,ftype), file=sys.stderr)
|
||||
else:
|
||||
print >>sys.stderr,"I have no copy of %s.%s"%(key,ftype)
|
||||
print("I have no copy of %s.%s"%(key,ftype), file=sys.stderr)
|
||||
try:
|
||||
downloadFile(key, ftype, section, url)
|
||||
print "Downloaded",url
|
||||
except UIError, e:
|
||||
print >>sys.stderr, str(e)
|
||||
print("Downloaded",url)
|
||||
except UIError as e:
|
||||
print(str(e), file=sys.stderr)
|
||||
errors.append((key,ftype,url,str(e)))
|
||||
except (IOError, socket.error), e:
|
||||
except (IOError, socket.error) as e:
|
||||
msg = "Error downloading %s: %s"%(url,str(e))
|
||||
print >>sys.stderr, msg
|
||||
print(msg, file=sys.stderr)
|
||||
errors.append((key,ftype,url,msg))
|
||||
if urls.has_key("ps") and not urls.has_key("ps.gz"):
|
||||
if "ps" in urls and "ps.gz" not in urls:
|
||||
# Say, this is something we'd like to have gzipped locally.
|
||||
psFname = getCacheFname(key, "ps", section)
|
||||
psGzFname = getCacheFname(key, "ps.gz", section)
|
||||
if os.path.exists(psFname) and not os.path.exists(psGzFname):
|
||||
# This is something we haven't gzipped yet.
|
||||
print "Compressing a copy of",psFname
|
||||
print("Compressing a copy of",psFname)
|
||||
outf = gzip.GzipFile(psGzFname, "wb")
|
||||
inf = open(psFname, "rb")
|
||||
while 1:
|
||||
@ -156,9 +156,9 @@ def downloadAll(bibtex, missingOnly=0):
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 2:
|
||||
print "Loading from %s"%sys.argv[1]
|
||||
print("Loading from %s"%sys.argv[1])
|
||||
else:
|
||||
print >>sys.stderr, "Expected a single configuration file as an argument"
|
||||
print("Expected a single configuration file as an argument", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
config.load(sys.argv[1])
|
||||
|
||||
|
@ -9,10 +9,10 @@ import os
|
||||
import json
|
||||
|
||||
assert sys.version_info[:3] >= (2,2,0)
|
||||
os.umask(022)
|
||||
os.umask(0o22)
|
||||
|
||||
import BibTeX
|
||||
import config
|
||||
from . import BibTeX
|
||||
from . import config
|
||||
|
||||
def getTemplate(name):
|
||||
f = open(name)
|
||||
@ -39,15 +39,15 @@ def writeBody(f, sections, section_urls, cache_path, base_url):
|
||||
sDisp = re.sub(r'\s+', ' ', s.strip())
|
||||
sDisp = sDisp.replace(" ", " ")
|
||||
if u:
|
||||
print >>f, ('<li><h3><a name="%s"></a><a href="%s">%s</a></h3>'%(
|
||||
(BibTeX.url_untranslate(s), u, sDisp)))
|
||||
print(('<li><h3><a name="%s"></a><a href="%s">%s</a></h3>'%(
|
||||
(BibTeX.url_untranslate(s), u, sDisp))), file=f)
|
||||
else:
|
||||
print >>f, ('<li><h3><a name="%s">%s</a></h3>'%(
|
||||
BibTeX.url_untranslate(s),sDisp))
|
||||
print >>f, "<ul class='expand'>"
|
||||
print(('<li><h3><a name="%s">%s</a></h3>'%(
|
||||
BibTeX.url_untranslate(s),sDisp)), file=f)
|
||||
print("<ul class='expand'>", file=f)
|
||||
for e in entries:
|
||||
print >>f, e.to_html(cache_path=cache_path, base_url=base_url)
|
||||
print >>f, "</ul></li>"
|
||||
print(e.to_html(cache_path=cache_path, base_url=base_url), file=f)
|
||||
print("</ul></li>", file=f)
|
||||
|
||||
def writeHTML(f, sections, sectionType, fieldName, choices,
|
||||
tag, config, cache_url_path, section_urls={}):
|
||||
@ -69,7 +69,7 @@ def writeHTML(f, sections, sectionType, fieldName, choices,
|
||||
|
||||
#
|
||||
tagListStr = []
|
||||
st = config.TAG_SHORT_TITLES.keys()
|
||||
st = list(config.TAG_SHORT_TITLES.keys())
|
||||
st.sort()
|
||||
root = "../"*pathLength(config.TAG_DIRECTORIES[tag])
|
||||
if root == "": root = "."
|
||||
@ -104,10 +104,10 @@ def writeHTML(f, sections, sectionType, fieldName, choices,
|
||||
}
|
||||
|
||||
header, footer = getTemplate(config.TEMPLATE_FILE)
|
||||
print >>f, header%fields
|
||||
print(header%fields, file=f)
|
||||
writeBody(f, sections, section_urls, cache_path=cache_url_path,
|
||||
base_url=root)
|
||||
print >>f, footer%fields
|
||||
print(footer%fields, file=f)
|
||||
|
||||
def jsonDumper(obj):
|
||||
if isinstance(obj, BibTeX.BibTeXEntry):
|
||||
@ -125,7 +125,7 @@ def writePageSet(config, bib, tag):
|
||||
bib_entries = bib.entries[:]
|
||||
|
||||
if not bib_entries:
|
||||
print >>sys.stderr, "No entries with tag %r; skipping"%tag
|
||||
print("No entries with tag %r; skipping"%tag, file=sys.stderr)
|
||||
return
|
||||
|
||||
tagdir = config.TAG_DIRECTORIES[tag]
|
||||
@ -133,7 +133,7 @@ def writePageSet(config, bib, tag):
|
||||
cache_url_path = BibTeX.smartJoin("../"*pathLength(tagdir),
|
||||
config.CACHE_DIR)
|
||||
if not os.path.exists(outdir):
|
||||
os.makedirs(outdir, 0755)
|
||||
os.makedirs(outdir, 0o755)
|
||||
##### Sorted views:
|
||||
|
||||
## By topic.
|
||||
@ -174,7 +174,7 @@ def writePageSet(config, bib, tag):
|
||||
except ValueError:
|
||||
last_year = int(entries[-2][1][0].get('year'))
|
||||
|
||||
years = map(str, range(first_year, last_year+1))
|
||||
years = list(map(str, list(range(first_year, last_year+1))))
|
||||
if entries[-1][0] == 'Unknown':
|
||||
years.append("Unknown")
|
||||
|
||||
@ -216,15 +216,15 @@ def writePageSet(config, bib, tag):
|
||||
|
||||
header,footer = getTemplate(config.BIBTEX_TEMPLATE_FILE)
|
||||
f = open(os.path.join(outdir,"bibtex.html"), 'w')
|
||||
print >>f, header % { 'command_line' : "",
|
||||
print(header % { 'command_line' : "",
|
||||
'title': config.TAG_TITLES[tag],
|
||||
'root': root }
|
||||
'root': root }, file=f)
|
||||
for ent in entries:
|
||||
print >>f, (
|
||||
print((
|
||||
("<tr><td class='bibtex'><a name='%s'>%s</a>"
|
||||
"<pre class='bibtex'>%s</pre></td></tr>")
|
||||
%(BibTeX.url_untranslate(ent.key), ent.key, ent.format(90,8,1)))
|
||||
print >>f, footer
|
||||
%(BibTeX.url_untranslate(ent.key), ent.key, ent.format(90,8,1))), file=f)
|
||||
print(footer, file=f)
|
||||
f.close()
|
||||
|
||||
f = open(os.path.join(outdir,"bibtex.json"), 'w')
|
||||
@ -234,13 +234,13 @@ def writePageSet(config, bib, tag):
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 2:
|
||||
print "Loading from %s"%sys.argv[1]
|
||||
print("Loading from %s"%sys.argv[1])
|
||||
else:
|
||||
print >>sys.stderr, "Expected a single configuration file as an argument"
|
||||
print("Expected a single configuration file as an argument", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
config.load(sys.argv[1])
|
||||
|
||||
bib = BibTeX.parseFile(config.MASTER_BIB)
|
||||
|
||||
for tag in config.TAG_DIRECTORIES.keys():
|
||||
for tag in list(config.TAG_DIRECTORIES.keys()):
|
||||
writePageSet(config, bib, tag)
|
||||
|
@ -1,103 +0,0 @@
|
||||
{% trans -%}
|
||||
=================================================================
|
||||
I2P 2.4.0 Release with Congestion and NetDB Security improvements
|
||||
=================================================================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2023-12-18
|
||||
:category: release
|
||||
:excerpt: {% trans %}{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Update details
|
||||
{%- endtrans %}
|
||||
============================================
|
||||
|
||||
{% trans -%}
|
||||
This release, I2P 2.4.0, continues our effort to improve the security and stability of the I2P network.
|
||||
It contains significant improvements to the Network Database, an essential structure within the I2P network used for disovering your peers.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
The congestion handling changes will improve network stability by giving routers the ability to relieve congested peers by avoiding them.
|
||||
This will help the network limit the effect of tunnel spam.
|
||||
It will also help the network heal during and after DDoS attacks.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
The NetDb changes also help secure individual routers and the applications that use them.
|
||||
Routers can now defend against attackers by separating the NetDB into multiple "Sub-DB's" which we use to prevent information leaks between applications and the router.
|
||||
This also improves the information available to Java routers about their NetDB activity and simplifies our support for multihoming applications.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Also included are a number of bug fixes and enhancements across the I2PSnark and SusiMail applications.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}i2psnark: Uncomment and fix local torrent file picker{% endtrans %}
|
||||
- {% trans %}NetDB: Lookup handler/throttler fixes{% endtrans %}
|
||||
- {% trans %}Router: Restructure netDb to isolate data recieved as a client from data recieved as a router{% endtrans %}
|
||||
- {% trans %}Router: Implement handling and penalties for congestion caps{% endtrans %}
|
||||
- {% trans %}Router: Temporarily ban routers publishing in the future{% endtrans %}
|
||||
- {% trans %}Transports: Disable SSU 1{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}Addressbook: Workaround for i2p-projekt.i2p etag bug (Gitlab #454){% endtrans %}
|
||||
- {% trans %}Console: Clear out "proxy must be running" status after success{% endtrans %}
|
||||
- {% trans %}Console: Don't lose tabs in log messages{% endtrans %}
|
||||
- {% trans %}Console: Fix sidebar not immediately showing results of manual update check{% endtrans %}
|
||||
- {% trans %}Console: Fix visibility of radio/checkboxes (light theme){% endtrans %}
|
||||
- {% trans %}Console: Prevent overflow of sidebar status{% endtrans %}
|
||||
- {% trans %}Debian: Change JRE dependency order (Gitlab #443, Debian #1024461){% endtrans %}
|
||||
- {% trans %}i2psnark: Increase comment bucket size to reduce duplicates{% endtrans %}
|
||||
- {% trans %}i2psnark: Prevent start-all from within search results erroring (Gitlab #445){% endtrans %}
|
||||
- {% trans %}i2ptunnel: Exempt tunnel name from XSS filter (Gitlab #467){% endtrans %}
|
||||
- {% trans %}i2ptunnel: Fix gzip footer check in GunzipOutputStream (Gitlab #458){% endtrans %}
|
||||
- {% trans %}i2ptunnel: Remove nonstandard Proxy-Connection headers (Gitlab #452){% endtrans %}
|
||||
- {% trans %}NTCP2: Fix updating address on transition to firewalled (Gitlab #435){% endtrans %}
|
||||
- {% trans %}SAM: Fix accept after soft restart (Gitlab #399){% endtrans %}
|
||||
- {% trans %}SAM: Reset incoming socket if no subsession is matched (Gitlab #456){% endtrans %}
|
||||
- {% trans %}SSU2: Fix uncaught IAE caused by itags with zero values (Gitlab #415){% endtrans %}
|
||||
- {% trans %}SSU2: Prevent rare IAE in peer test timer (Gitlab #433){% endtrans %}
|
||||
- {% trans %}Susimail: Dark theme fixes{% endtrans %}
|
||||
- {% trans %}Susimail: Fix binary content-encoding{% endtrans %}
|
||||
- {% trans %}Susimail: Fix incorrect "previous" icons{% endtrans %}
|
||||
- {% trans %}Susimail: Fix setting encoding for attachments{% endtrans %}
|
||||
- {% trans %}Susimail: Flush output to fix truncated mails{% endtrans %}
|
||||
- {% trans %}Sybil: Don't ban NAT64 addresses{% endtrans %}
|
||||
- {% trans %}Transport: Fix NPE during soft restart (Gitlab #437){% endtrans %}
|
||||
- {% trans %}UPnP: Fix handing of multiple IGDs{% endtrans %}
|
||||
- {% trans %}UPnP: Fix missing port in Host header causing failures on libupnp-based devices{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- API 0.9.61
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.4.0
|
||||
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
d08db62457d4106ca0e36df3487bdf6731cbb81045b824a003cde38c7e1dfa27 i2pinstall_2.4.0_windows.exe
|
||||
ef5f3d0629fec292aae15d027f1ecb3cc7f2432a99a5f7738803b453eaad9cad i2pinstall_2.4.0.jar
|
||||
30ef8afcad0fffafd94d30ac307f86b5a6b318e2c1f44a023005841a1fcd077c i2psource_2.4.0.tar.bz2
|
||||
97be217bf07319a50b6496f932700c3f3c0cceeaf1e0643260d38c9e6e139b53 i2pupdate_2.4.0.zip
|
||||
8f4a17a8cbadb2eabeb527a36389fd266a4bbcfd9d634fa4f20281f48c486e11 i2pupdate.su3
|
||||
|
@ -1,84 +0,0 @@
|
||||
{% trans -%}
|
||||
========================================
|
||||
Many Masks, One Mind: Securing the NetDB
|
||||
========================================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-03-29
|
||||
:category: development
|
||||
:excerpt: {% trans %}Many Masks, One Mind: Securing the NetDB{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Author's note: the attacks referred to in this article are not possible against current versions of I2P.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As a self-organizing peer-to-peer network, I2P relies on the routers participating in the network to have a way to share information about what is on the network and how to reach it.
|
||||
I2P routers achieve this information sharing using the NetDB, a DHT based on Kademlia but modified to work for I2P.
|
||||
The NetDB needs to share two main kinds of entries, "RouterInfos" which peers will use to communicate with other routers directly, and "LeaseSets" which other peers will use to communicate with I2P clients through anonymous tunnels.
|
||||
Routers are frequently commmunicating NetDB entries with eachother, either by sending the information to a router or client, or requesting information from a router or client.
|
||||
This means that the entries can arrive directly or indirectly, anonymously or non-anonymously, depending on the needs of the network and the capabilities of the client.
|
||||
However, as an anonymizing network, it is also important that it remain impossible for information sent anonymously to be requested back non-anonymously.
|
||||
It is also important and for information sent non-anonymously to be impossible to request back anonymously.
|
||||
If it becomes possible for either of those situations to occur, then a linking attack may be carried out which allows an attacker to determine if a clients and routers are sharing a common view of the NetDB.
|
||||
If it can be reliably determined that the 2 targets share a common view of the NetDB, then there's a very good chance they are on the same router, weakening the target's anonymity drastically.
|
||||
Because there are so few anonymizing networks, and I2P is the only one where the routing table is shared via the operation of a DHT, this class of attack is all but unique to I2P and its resolution is important to I2P's success.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Consider the following scenario: There is an I2P router hosting an I2P client.
|
||||
The router publishes a RouterInfo, and the I2P client publishes its LeaseSet.
|
||||
Because they are both published in the NetDB, other I2P routers can query the NetDB to discover how to communicate with them.
|
||||
This is normal and essential to the operation of an overlay network of the type implemented by I2P.
|
||||
An attacker runs an I2P router and queries the NetDB for the target RouterInfo and the target LeaseSet.
|
||||
It then crafts a new LeaseSet which is unique and and potentially even fake, and sends it down a tunnel to the LeaseSet for the client it is targeting for attack.
|
||||
The client processes the crafted LeaseSet and adds it to its own NetDB.
|
||||
The attacker then requests the crafted LeaseSet back directly, from the router, using the RouterInfo it got from the NetDB.
|
||||
If the crafted LeaseSet is received back as a reply, then the attacker can conclude that the target client and the target router share a common view of the NetDB.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
That is a simple example of a NetDB deanonymization attack class which relies on adding an entry into another person's NetDB with one identity, and then requesting it back out with another identity.
|
||||
In this case, the identities in question are the "router" and the "client" identity.
|
||||
However, client-to-client linking, which is less damaging, is also possible in some designs.
|
||||
Designing a defense against this class of attack requires giving the router a way of determining whether or not it is safe to communicate a piece of information with a potential identity.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
So how should we think about this problem?
|
||||
What we're dealing with here, really, has to do with the linkability of different "identities" on the network.
|
||||
The possibility of linking is created because all these identities share a common datastructure which "remembers" who it has communicated with, and who has communicated with it.
|
||||
It also "remembers" how that communication occurred.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
For a moment, we should imagine ourselves as an attacker.
|
||||
Imagine if you were trying to discover the identity of a master of disguise.
|
||||
You know for sure you have seen his real face, and you know for sure that you regularly communicate with one of his disguises.
|
||||
How would you go about establishing that the disguise identity and the real identity belong to the same person?
|
||||
I might tell the disguised person a secret.
|
||||
If the non-disguised person responds by using the secret information, then I can determine that the non-disguised person knows the secret.
|
||||
Under the assumption that the disguised person did not communicate the secret to anyone else, then I can assume that the non-disguised person and the disguised person are in fact, the same person.
|
||||
No matter how many masks the master of disguise wears, he has but one mind.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
In order to successfully protect the identities of I2P clients, I2P needs to be able to perform as a better master of disguise than the one described above.
|
||||
It needs to be able to "remember" several important pieces of information about how it has participated in the NetDB and respond appropriately based on those details.
|
||||
It must be able to recall:
|
||||
{%- endtrans %}
|
||||
|
||||
* {% trans -%}Whether a NetDB Entry was received directly, or received down a client tunnel{%- endtrans %}
|
||||
* {% trans -%}Whether a NetDB Entry was sent by a peer in response to our lookup, or sent unsolicited{%- endtrans %}
|
||||
* {% trans -%}Which NetDB Entry was received down Which client Tunnel{%- endtrans %}
|
||||
* {% trans -%}Multiple versions of the same entry for different client tunnels{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Structurally, the most understandable and reliable way to handle this pattern is to use "Sub-DBs."
|
||||
Sub-DB's are miniature NetDB's which serve to help the NetDB organize entries without losing track.
|
||||
Every client gets a Sub-DB for its own use, and the router itself gets a fully-fledged NetDB.
|
||||
Using Sub-DB's, we give our master of disguise a rolodex of secrets organized by who shared those secrets with him.
|
||||
When a request is sent to a client, it only looks for entries which have been communicated to the client, and when a request is sent to a router, only the router-wide NetDB is used.
|
||||
By doing things this way, we resolve not only the simplest form of the attack, but also undermine the potency of the entire attack class.
|
||||
{%- endtrans %}
|
@ -1,93 +0,0 @@
|
||||
{% trans -%}
|
||||
=====================
|
||||
New Release I2P 2.5.0
|
||||
=====================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-04-08
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.5.0 release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
This release, I2P 2.5.0, provides more user-facing improvements than the 2.4.0 release, which was focused on implementing the NetDB isolation strategy.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
New features have been added to I2PSnark like the ability to search through torrents.
|
||||
Bugs have been fixed to improve compatibility with other I2P torrent clients like BiglyBT and qBittorrent.
|
||||
We would like to thank all of the developers who have worked with libtorrent and qBittorrent to enable and improve their I2P support.
|
||||
New features have also been added to SusiMail including support for Markdown formatting in emails and the ability to drag-and-drop attachments into emails.
|
||||
Tunnels created with the Hidden Services manager now support "Keepalive" which improves performance and compatibility with web technologies, enabling more sophisticated I2P sites.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
During this release we also made several tweaks to the NetDB to improve its resilience to spam and to improve the router's ability to reject suspicious messages.
|
||||
This was part of an effort to "audit" the implementation of "Sub-DB isolation" defenses from the 2.4.0 release.
|
||||
This investigation uncovered one minor isolation-piercing event which we repaired.
|
||||
This issue was discovered and fixed internally by the I2P team.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
During this release several improvements were made to the process of releasing our downstream distributions for Android and Windows.
|
||||
This should result in improved delivery and availability for these downstream products.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}I2PTunnel: Implement support for Keepalive/Server-side Persistence{% endtrans %}
|
||||
- {% trans %}Susimail: Add markdown support for formatted plain-text content{% endtrans %}
|
||||
- {% trans %}Susimail: Add HTML Email support{% endtrans %}
|
||||
- {% trans %}I2PSnark: Add search capability{% endtrans %}
|
||||
- {% trans %}I2PSnark: Preserve private=0 in torrent files{% endtrans %}
|
||||
- {% trans %}Data: Store compressed RI and LS{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}Susimail: Fix handling of forwarded mail with attachments{% endtrans %}
|
||||
- {% trans %}Susimail: Fix handling of forwarded mail with unspecified encoding{% endtrans %}
|
||||
- {% trans %}Susimail: Fix forwarding of HTML-only email{% endtrans %}
|
||||
- {% trans %}Susimail: Bugfixes in presentation of encoded attachmments, mail body{% endtrans %}
|
||||
- {% trans %}I2PSnark: Handle data directory changes{% endtrans %}
|
||||
- {% trans %}SSU2: Cancel peer test if Charlie does not have B cap{% endtrans %}
|
||||
- {% trans %}SSU2: Treat peer test result as unknown if Charlie is unreachable{% endtrans %}
|
||||
- {% trans %}Router: Filter additional garlic-wrapped messages{% endtrans %}
|
||||
- {% trans %}I2CP: Prevent loopback messages to same session{% endtrans %}
|
||||
- {% trans %}NetDB: Resolve Exploratory/Router isolation-piercing event{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- API 0.9.62
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.5.0
|
||||
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
i2pinstall_2.5.0-0.jar - 61d3720accc6935f255611680b08ba1a414d32daa00d052017630c2424c30069
|
||||
i2pinstall_2.5.0-0_windows.exe - a0d84c519f3c35874a9f661b9f40220e5a1d29716166c682e2bd1ee15ff83f33
|
||||
i2pinstall_2.5.0.jar - 61d3720accc6935f255611680b08ba1a414d32daa00d052017630c2424c30069
|
||||
i2pinstall_2.5.0.jar.sig - c8a6d79909d06ac6bca23d8e890765c6e6ed21a535f7529e0708797fdaf9fc1b
|
||||
i2pinstall_2.5.0_windows.exe - 762b9d672dfff0baccd46f970deb5a2621358d1e2dfc0dd85a78aecda3623ac6
|
||||
i2pinstall_2.5.0_windows.exe.sig - 103a1bd155110514fe9ae075243cc66e2fef866353165b2c806248e15925e957
|
||||
i2psource_2.5.0.tar.bz2 - 6bda9aff7daa468cbf6ddf141c670140de4d1db145329645a90c22c1e5c7bc01
|
||||
i2psource_2.5.0.tar.bz2.sig - a1d0ea6f2051ed0643bc2c0207a2cf594f2b2bc4303ac49cd6a43baaf0558f62
|
||||
i2pupdate-2.5.0.su3 - 7bcfc3df3a14a0b9313b9a0fe20e56db75267d5afcfd8a3203fbfcfac46deae4
|
||||
i2pupdate-2.5.0.su3.torrent - a7dd76348bf404d84a67bda8b009d54cc08748c036988dbe78bff6ca6928950c
|
||||
i2pupdate.su3 - 7bcfc3df3a14a0b9313b9a0fe20e56db75267d5afcfd8a3203fbfcfac46deae4
|
||||
i2pupdate.zip - d0a4cfe6cb587e0ffabcfb6012682f400a38ee87f23fa90f8a18f25e77b742d8
|
||||
i2pupdate_2.5.0.zip - d0a4cfe6cb587e0ffabcfb6012682f400a38ee87f23fa90f8a18f25e77b742d8
|
||||
i2pupdate_2.5.0.zip.sig - 411eb4ca31e2984dae4c943136411e8ee85435f59749391edefec07509cfd5af
|
||||
|
@ -1,21 +0,0 @@
|
||||
{% trans -%}
|
||||
==============
|
||||
Stormy Weather
|
||||
==============
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-04-25
|
||||
:category: release
|
||||
:excerpt: {% trans %}Stormy Weather{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
The I2P network is currently under a Denial-of-Service attack.
|
||||
This attack affects I2P and i2pd but in different ways and is having a serious effect on network health.
|
||||
Reachability of I2P sites is badly degraded.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
If you are hosting a service inside I2P and it is hosted on a Floodfill router, you should consider multihoming the service on a Floodfill-disabled router to improve reachability.
|
||||
Other mitigations are being discussed but a long-term, backward-compatible solution is still being worked on.
|
||||
{%- endtrans %}
|
@ -1,60 +0,0 @@
|
||||
{% trans -%}
|
||||
=====================
|
||||
New Release I2P 2.5.1
|
||||
=====================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-05-06
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.5.1 Release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P 2.5.1 is being released to address Denial-of-Service Attacks affecting the I2P network and services.
|
||||
With this release we disable the IP-based parts of the Sybil attack detection tool which were targeted to amplify the effect and duration of the attack.
|
||||
This should help the network return to normal operation.
|
||||
Those of you who have disabled the Sybil attack detection tool may safely re-enable it.
|
||||
Adjustments to other subsystems to improve RouterInfo validation and peer selection have also been made.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}Susimail: Add search box{% endtrans %}
|
||||
- {% trans %}Susimail: UI Improvements{% endtrans %}
|
||||
- {% trans %}NetDB: Don't lookup RI if on banlist{% endtrans %}
|
||||
- {% trans %}Tomcat: update to 9.0.88{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}Sybil: Disable IP-Closeness Checks in Sybil Attack Analysis Tool{% endtrans %}
|
||||
- {% trans %}Profiles: Don't update last heard from if tunnel fails{% endtrans %}
|
||||
- {% trans %}NetDB: Improve validation of RI's before storing, sending RI's{% endtrans %}
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.5.1
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
1b0c1a12e64bd6dabd894a297b7bfd60ebe218a9177086f27367b8d4f1e30ab9 i2pinstall_2.5.1-0.jar
|
||||
f9b2038cc6376a7b67a7cbc6ff07046b0a5f6146658dfb910ca4532c81263177 i2pinstall_2.5.1-0_windows.exe
|
||||
1b0c1a12e64bd6dabd894a297b7bfd60ebe218a9177086f27367b8d4f1e30ab9 i2pinstall_2.5.1.jar
|
||||
d0150a4f7abcdc85cddae277fa951c2ee76ccc7403d98cd255791ac752a7e36b i2pinstall_2.5.1.jar.sig
|
||||
f9b2038cc6376a7b67a7cbc6ff07046b0a5f6146658dfb910ca4532c81263177 i2pinstall_2.5.1_windows.exe
|
||||
4bc7e59ee0036389a0f76fc76b2303eeae62bf6eaaf608c9939226febf9ddeae i2psource_2.5.1.tar.bz2
|
||||
251293c39c333bd7d8ad01235ef15bccf15df1b72dd18917de06cdb212b7801f i2psource_2.5.1.tar.bz2.sig
|
||||
163b7fe3e9941bd412bad1b80f34e2a8cd1ade2e77cbe4cfb58eca42f3ca4b62 i2pupdate-2.5.1.su3
|
||||
461b5fe51d2d953ba798eee867e434b4bf234911418c0dd5560b558f755f6657 i2pupdate-2.5.1.su3.torrent
|
||||
a4db0e6a9ee56df2d9bb2b12d9eb3a04501aeeac83773817f62565e632d88228 i2pupdate_2.5.1.zip
|
||||
c592bc6d1ffcc988f021bbd30ea6e5063f31bb5175846be96c5c2724294bd99b i2pupdate_2.5.1.zip.sig
|
||||
163b7fe3e9941bd412bad1b80f34e2a8cd1ade2e77cbe4cfb58eca42f3ca4b62 i2pupdate.su3
|
||||
a4db0e6a9ee56df2d9bb2b12d9eb3a04501aeeac83773817f62565e632d88228 i2pupdate.zip
|
@ -1,50 +0,0 @@
|
||||
===========================================
|
||||
{% trans -%}2.5.2 Release{%- endtrans %}
|
||||
===========================================
|
||||
|
||||
.. meta::
|
||||
:author: zzz
|
||||
:date: 2024-05-15
|
||||
:category: release
|
||||
:excerpt: {% trans %}2.5.2 Release with HTTP fix{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P 2.5.2 is released to fix a bug introduced in 2.5.0 causing truncation of some HTTP content.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}Console: Update rrd4j to 3.9.1-preview{% endtrans %}
|
||||
- {% trans %}Router: Publish G cap if symmetric natted{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}i2ptunnel: Fix bug causing truncation of some HTTP content{% endtrans %}
|
||||
- {% trans %}i2ptunnel: Fix custom option form width (light theme){% endtrans %}
|
||||
- {% trans %}Tunnels: Fix selection of peers with expired RIs{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.5.2
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
1aa1ac29620886a7d744424318287c67dc9ead488e6ab434848597ee9db7ce18 i2pinstall_2.5.2_windows.exe
|
||||
751f48cfb380c8796bd645621b149114d55f32cd4330784cb287be9413b02569 i2pinstall_2.5.2.jar
|
||||
f23d0746d72a55cccbd17f40762e491ae1b42cdf55d7e73404d213a84985ca73 i2psource_2.5.2.tar.bz2
|
||||
adba8b7512d27a44ed876ec4beb39a82ebb34dc243ec024aff289e91823fc0c7 i2pupdate_2.5.2.zip
|
||||
0d1d09d3d8199ea1a2ea983f5023125449ea55e93e20f5fbf1b7ad9e466bb6fc i2pupdate.su3
|
@ -1,67 +0,0 @@
|
||||
============================================
|
||||
{% trans -%}I2P 2.6.0 Release{%- endtrans %}
|
||||
============================================
|
||||
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-07-19
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.6.0 Release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
This release, I2P 2.6.0, continues our work by fixing bugs, adding features, and improving the network's reliability.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Newer routers will be favored when selecting floodfill routers.
|
||||
I2PSnark received features which improve the performance of PeX(Peer Exchange), in addition to bug fixes.
|
||||
Legacy transport protocols are being removed, simplifying the code in the UDP transports.
|
||||
Locally-hosted destination will be reachable by local clients without requesting their LeaseSet, improving performance and testability.
|
||||
Additional tweaks were made to peer selection strategies.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P no longer allows I2P-over-Tor, connections from Tor exit IP addresses are now blocked.
|
||||
We discourage this because it degrades the performance of I2P and uses up the resources of Tor exits for no benefit.
|
||||
If you are a helpful person running both a Tor Exit and I2P we encourage you to continue to do so, using different IP addresses for each.
|
||||
Non-exit relays and Tor clients are unaffected by this and do not need to change anything.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}Router: Increase minimum version for floodfill routers{% endtrans %}
|
||||
- {% trans %}Router: Disable I2P over Tor{% endtrans %}
|
||||
- {% trans %}Address Book: Cache locally hosted destinations{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}I2PSnark: Peer Exchange Tweaks{% endtrans %}
|
||||
- {% trans %}I2PSnark: Bugfixes{% endtrans %}
|
||||
- {% trans %}Router: Peer Selection Tweaks{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.6.0
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
13f2e6b3cc9716c89c4d4d3bc9918171fbad5f450171e1c32b1237b5421bc065 i2pinstall_2.6.0_windows.exe
|
||||
42ac34e4c67cf5e2582853f0cf3074f6a73ea59503e1350e1b687cee3f849814 i2pinstall_2.6.0_windows.exe.sig
|
||||
24cda3f04e8c2e976b73bd45d36d0e31217e28fbe3019bf9a9d839b45d60537a i2pinstall_2.6.0.jar
|
||||
249b35c1e061e194ee18048b0644cc5e2c5cf785ffce655e3124eb959dc189ff i2psource_2.6.0.tar.bz2
|
||||
2867d752f6fb89a7a5ada4f4123ca601ad8d78ff78f553a9269bf0ddffe724ca i2pupdate_2.6.0.zip
|
||||
be6ac988497ac0336d21cdfc57bbbe3cc5cffd983ac3282fd8ea11914e18e7ee i2pupdate.su3
|
@ -1,49 +0,0 @@
|
||||
===========================================
|
||||
{% trans -%}2.6.1 Release{%- endtrans %}
|
||||
===========================================
|
||||
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-08-06
|
||||
:category: release
|
||||
:excerpt: {% trans %}2.6.1 Release with I2PTunnel UI fix{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P 2.6.1 is released in order to fix a User-Interface bug in the Hidden Services Manager application.
|
||||
This bug caused scrolling to be disabled, rendering some configuration inaccessible.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}Graphs: render graphs in svg{% endtrans %}
|
||||
- {% trans %}Translations: generate internal translation leaderboard{% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}i2ptunnel: Fix bug causing truncation configuration UI{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.6.1
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
88e69e0adac66ed41ef1d521c373a40d491fbec1a40f596dbaa56ac67b5c4b0d i2pinstall_2.6.1_windows.exe
|
||||
c10d74075dac39d0f80c4fa5bbd403ed59aeba5e933e761a0ecf59d8d5afcad1 i2pinstall_2.6.1.jar
|
||||
e6ce1704da6ac44909b9ee74b376e3ba10d27a287840b28caaf51dfae0903901 i2psource_2.6.1.tar.bz2
|
||||
e78fe71186b7b194882132b0392dceb9b4f2ea35cabfcb224739f46f1b11cd53 i2pupdate_2.6.1.zip
|
||||
42a4eac2a1802130f38ee648cc04c0f2cbc6e8ca6975d89235bdf80b3000aded i2pupdate.su3
|
@ -1,14 +0,0 @@
|
||||
===========================================
|
||||
{% trans -%}I2P Easy-Install for Windows 2.6.1 Release{%- endtrans %}
|
||||
===========================================
|
||||
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-08-26
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P Easy-Install Windows 2.6.1 Release with I2PTunnel UI fix{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
This release updates the embedded I2P router to I2P 2.6.1.
|
||||
It also updates the embedded I2P Firefox profile to 2.6.2.
|
||||
{%- endtrans %}
|
@ -1,49 +0,0 @@
|
||||
{% trans -%}
|
||||
==================
|
||||
I2P 2.7.0 Released
|
||||
==================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2024-10-09
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.7.0 Released{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
This release, I2P 2.7.0, continues our work by fixing bugs, improving performance, and adding features.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Access to information from the console and applications has been improved.
|
||||
Issues have been fixed in I2PSnark and SusiMail search.
|
||||
The netDB search embedded into the router console now operates in a more intuitive and useful way.
|
||||
Minor improvements have been made to diagnostic displays in advanced mode.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Bugs have also been fixed to improve compatibility within the network.
|
||||
An issue with publishing leaseSets was solved which improves reliability major hidden services.
|
||||
I2PSnark no longer changes the infohash when a user changes only the trackers on an existing torrent.
|
||||
This prevents torrents from being unnecessarily disrupted by these changes.
|
||||
We welcomed this contribution from a new contributor.
|
||||
A conflict in the handling of a streaming library option was resolved to improve compatibility with other I2P implementations.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.7.0
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
d70ee549b05e58ded4b75540bbc264a65bdfaea848ba72631f7d8abce3e3d67a i2pinstall_2.7.0_windows.exe
|
||||
ea3872af06f7a147c1ca84f8e8218541963da6ad97e30e1d8f7a71504e4b0cee i2pinstall_2.7.0.jar
|
||||
54eebdb1cfdbe6aeb1f60e897c68c6b2921c36ce921350d45d21773256c99874 i2psource_2.7.0.tar.bz2
|
||||
b7fae5181cbd8b60be0d5a05e391f4c9d114748a8240eb64b91ee84da5c659f8 i2pupdate_2.7.0.zip
|
||||
59d3d61eccf3622985b71e06d454f61f32f39baa1eb9064536d295b4a7e7ae4e i2pupdate.su3
|
@ -1,40 +0,0 @@
|
||||
{% trans -%}
|
||||
==================
|
||||
I2P 2.8.0 Released
|
||||
==================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2025-02-04
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.8.0 Released{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
This release improves I2P by fixing bugs, removing unused code, and improving network stability.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
We have improved handling of congested routers in the network.
|
||||
Issues in UPnP and NAT traversal were addressed to improve connectivity and error reporting.
|
||||
We now have a more aggressive strategy for leaseset removal from the NetDb to improve router performance and mitigate overload.
|
||||
Other changes were implemented to reduce the observability of events like a router rebooting or shutting down.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.8.0
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
f2699359fd7c5a2fddb5730666e61c0dce2184f95507d4f33dcfaca16569b580 i2pinstall_2.8.0_windows.exe
|
||||
32255865c5f89bceab4902ba401c971c5aa238ebe8bc1bfb2153acb6478ce656 i2pinstall_2.8.0.jar
|
||||
06b305c24ed163bb09b1afaa3a8d44b2477eb3eb0e1c84236d210606986bd820 i2psource_2.8.0.tar.bz2
|
||||
3ff1e0c52757a39e20ac864aa610c92f1a1168979b42a61cd1e9284becc0fe22 i2pupdate_2.8.0.zip
|
||||
bfc6fc3c6e2cb486448450d3f08cef6afe2966b57113b17df65cbb53ed6d4a82 i2pupdate.su3
|
@ -1,76 +0,0 @@
|
||||
===========================================
|
||||
{% trans -%}2.8.1 Release{%- endtrans %}
|
||||
===========================================
|
||||
|
||||
.. meta::
|
||||
:author: zzz
|
||||
:date: 2025-03-17
|
||||
:category: release
|
||||
:excerpt: {% trans %}2.8.1 Release with local site access fix{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
2.8.1 fixes accesses to local sites that were broken in 2.8.0.
|
||||
We have added notification bubbles to several applications in the console to highlight application messages.
|
||||
We fixed a tunnel test bug that may have been affecting tunnel reliability.
|
||||
The addressbook now has a new "latest" tab that displays the newest hostnames added from your subscriptions.
|
||||
There are several dark theme fixes and improvements.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
We fixed the installer that previously failed on Java 21 or higher.
|
||||
We also fixed installing to directory paths that contain spaces on Linux.
|
||||
For those of you that use Docker, we updated outdated Docker container and container libraries.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Changes{% endtrans %}**
|
||||
|
||||
- {% trans %}New console notification bubbles{% endtrans %}
|
||||
- {% trans %}New addressbook sort-by-latest tab{% endtrans %}
|
||||
- {% trans %}Add support for .i2p.alt hostnames (RFC 9476){% endtrans %}
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}Fix local site access bug{% endtrans %}
|
||||
- {% trans %}Fix installer failure on Java 21+ (IzPack 5.2.4){% endtrans %}
|
||||
- {% trans %}Fix tunnel tests for outbound client tunnels{% endtrans %}
|
||||
- {% trans %}Fix installing to paths with spaces (non-Windows){% endtrans %}
|
||||
- {% trans %}Console dark theme fixes and improvements{% endtrans %}
|
||||
- {% trans %}Fix AIOOBE on large signed streaming packets{% endtrans %}
|
||||
- {% trans %}Fix compression of Router Identities{% endtrans %}
|
||||
- {% trans %}Update outdated Docker container and container libraries{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- {% trans %}Add logo to first installer panel{% endtrans %}
|
||||
- {% trans %}Add progress bar to installer panels{% endtrans %}
|
||||
- {% trans %}Use SHA256 pool in Noise{% endtrans %}
|
||||
- {% trans %}Move certs page to a debug page tab{% endtrans %}
|
||||
- {% trans %}Reduce memory usage in AddressBean{% endtrans %}
|
||||
- {% trans %}Set bulk profile for servers and i2psnark{% endtrans %}
|
||||
- {% trans %}Prep for tunnel bandwidth parameters (proposal 168){% endtrans %}
|
||||
- {% trans %}Proxy error page improvements{% endtrans %}
|
||||
- {% trans %}Check key order when parsing RI mappings{% endtrans %}
|
||||
- {% trans %}Reduce i2psnark peer check interval{% endtrans %}
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
|
||||
`{% trans %}Full list of fixed bugs{% endtrans %}`__
|
||||
|
||||
__ http://{{ i2pconv('git.idk.i2p') }}/i2p-hackers/i2p.i2p/-/issues?scope=all&state=closed&milestone_title=2.9.0
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
013f30db4116711fdb5f78f21f55da9a883a7de110f9c5b6d4f1390d60cc3441 i2pinstall_2.8.1_windows.exe
|
||||
a2f590156b6c58574c54860afb196886bc23e609ec26c3797ad0ef27289727f3 i2pinstall_2.8.1.jar
|
||||
6af1b88404527d9f5f88a29434979e048ac9d6fdc6ad7f5edbd0b318a1a1e57d i2psource_2.8.1.tar.bz2
|
||||
f4018ed081c0980f1cc4bc9e961ba49d7eda54babb06785220e54b54a58e150d i2pupdate_2.8.1.zip
|
||||
c89433df991876952fa2e4d7ebf2cb8c705911b80f240e6ddd3d8cba4aabed58 i2pupdate.su3
|
@ -1,43 +0,0 @@
|
||||
===========================================
|
||||
{% trans -%}2.8.2 Release{%- endtrans %}
|
||||
===========================================
|
||||
|
||||
.. meta::
|
||||
:author: zzz
|
||||
:date: 2025-03-29
|
||||
:category: release
|
||||
:excerpt: {% trans %}2.8.2 Release with SHA256 fix{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
2.8.2 fixes a bug causing SHA256 failures that was introduced in the 2.8.1 release.
|
||||
The bug primarily affects high-bandwidth routers.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}RELEASE DETAILS{% endtrans %}**
|
||||
|
||||
**{% trans %}Bug Fixes{% endtrans %}**
|
||||
|
||||
- {% trans %}Fix SHA256 double-free from Noise{% endtrans %}
|
||||
- {% trans %}Clear i2ptunnel bubble count when clearing status messages{% endtrans %}
|
||||
|
||||
**{% trans %}Other{% endtrans %}**
|
||||
|
||||
- {% trans %}Reduce memory usage in BanlistRenderer{% endtrans %}
|
||||
- {% trans %}Use torrent name instead of torrent file name in notifications{% endtrans %}
|
||||
- {% trans %}Translation updates{% endtrans %}
|
||||
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
7658f9ba7e28ab29ffeb3ec1909bf04f5ae391ee159980145ea01bd793c46f80 i2pinstall_2.8.2_windows.exe
|
||||
cd606827a9bca363bd6b3c89664772ec211d276cce3148f207643cc5e5949b8a i2pinstall_2.8.2.jar
|
||||
039b59fedd4a64aaeb6b74ab974310abdc9c08cb47ef1b8568c718965b50a485 i2psource_2.8.2.tar.bz2
|
||||
71cef41d7184516e42c15dc5105e52ab19960affd571b636e767e8bf8c227075 i2pupdate_2.8.2.zip
|
||||
15d886a9015dcf27ccc25e31b703ef6538b8b777176adf643dfe8ee0ba4984e0 i2pupdate.su3
|
@ -1,48 +0,0 @@
|
||||
{% trans -%}
|
||||
=============
|
||||
2.9.0 Release
|
||||
=============
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2025-06-02
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.9.0 Release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P 2.9.0 is a maintenance release that includes bug fixes and work on new features.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Thread usage has been improved to improve the performance of the i2ptunnel system.
|
||||
NTCP2 has been improved to resist probing attacks.
|
||||
The notification system has been integrated into more applications to provide better feedback to users from I2PSnark and the other applications.
|
||||
Automatic floodfill enrollment has been fixed.
|
||||
Users may observe increased resource usage when acting as floodfill.
|
||||
If this is not desired, floodfill mode can be disabled on the /config page.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
A new global map feature is available in the console which shows the locations of routers in your view of the netDb.
|
||||
These are the peers that help your router build tunnels and provide services anonymously.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Work continues on implementing automatic bandwidth management for tunnels, the Datagram2 protocol, and Post-Quantum cryptography.
|
||||
In two releases, at 2.11.0, I2P will require Java 17.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
681884cf79f001a360dd3635f7b31e889d407af8c3edb6fe89d841a5421ba563 i2pinstall_2.9.0_windows.exe
|
||||
f4474ca98914f18fce1a4ce37a6b3cd080499919e4202a29b8eae51798f0c7c1 i2pinstall_2.9.0.jar
|
||||
03989319e186d9b06ed96ea0efa6ac95af1bc57af956d7f5f06f52f8da64fcd7 i2psource_2.9.0.tar.bz2
|
||||
1b79b2593bbe60e08da3f84411d48a5f1fe0c8cfd934f1c90d2fece436c1f2b5 i2pupdate_2.9.0.zip
|
||||
2df2d63a65d9d8743098203919693185c910ddd8a53f13e91d5be7d95d1d0e82 i2pupdate.su3
|
@ -10,10 +10,10 @@ from i2p2www import helpers
|
||||
|
||||
|
||||
BLOG_METATAGS = {
|
||||
'author': u'I2P devs',
|
||||
'author': 'I2P devs',
|
||||
'category': None,
|
||||
'date': None,
|
||||
'excerpt': u'',
|
||||
'excerpt': '',
|
||||
}
|
||||
|
||||
BLOG_LIST_METATAGS = [
|
||||
|
@ -141,12 +141,12 @@ def downloads_config():
|
||||
def downloads_select(version, file):
|
||||
mirrors=read_mirrors()
|
||||
obj=[]
|
||||
for net in mirrors.keys():
|
||||
for net in list(mirrors.keys()):
|
||||
a={}
|
||||
a['key']=net
|
||||
a['name']=net
|
||||
a['protocols']=[]
|
||||
for protocol in mirrors[net].keys():
|
||||
for protocol in list(mirrors[net].keys()):
|
||||
b={}
|
||||
b['key']=protocol
|
||||
b['name']=protocol
|
||||
@ -166,13 +166,13 @@ def downloads_redirect(version, net, protocol, domain, file):
|
||||
}
|
||||
|
||||
if not protocol:
|
||||
protocol = mirrors.keys()[randint(0, len(mirrors) - 1)]
|
||||
protocol = list(mirrors.keys())[randint(0, len(mirrors) - 1)]
|
||||
if not protocol in mirrors:
|
||||
abort(404)
|
||||
mirrors=mirrors[protocol]
|
||||
|
||||
if not domain:
|
||||
domain = mirrors.keys()[randint(0, len(mirrors) - 1)]
|
||||
domain = list(mirrors.keys())[randint(0, len(mirrors) - 1)]
|
||||
if not domain in mirrors:
|
||||
abort(404)
|
||||
return render_template('downloads/redirect.html',
|
||||
|
@ -29,8 +29,8 @@ def we_are_frozen():
|
||||
def module_path():
|
||||
encoding = sys.getfilesystemencoding()
|
||||
if we_are_frozen():
|
||||
return os.path.dirname(unicode(sys.executable, encoding))
|
||||
return os.path.dirname(unicode(__file__, encoding))
|
||||
return os.path.dirname(str(sys.executable, encoding))
|
||||
return os.path.dirname(str(__file__, encoding))
|
||||
|
||||
|
||||
class HighlightExtension(Extension):
|
||||
|
@ -12,7 +12,7 @@
|
||||
import os
|
||||
import sys
|
||||
import os.path
|
||||
import StringIO
|
||||
import io
|
||||
|
||||
from pygments.formatter import Formatter
|
||||
from pygments.token import Token, Text, STANDARD_TYPES
|
||||
@ -27,11 +27,11 @@ __all__ = ['I2PHtmlFormatter', 'TextSpecFormatter']
|
||||
|
||||
|
||||
_escape_html_table = {
|
||||
ord('&'): u'&',
|
||||
ord('<'): u'<',
|
||||
ord('>'): u'>',
|
||||
ord('"'): u'"',
|
||||
ord("'"): u''',
|
||||
ord('&'): '&',
|
||||
ord('<'): '<',
|
||||
ord('>'): '>',
|
||||
ord('"'): '"',
|
||||
ord("'"): ''',
|
||||
}
|
||||
|
||||
kinds = {
|
||||
@ -459,7 +459,7 @@ class I2PHtmlFormatter(Formatter):
|
||||
"""
|
||||
if arg is None:
|
||||
arg = ('cssclass' in self.options and '.'+self.cssclass or '')
|
||||
if isinstance(arg, basestring):
|
||||
if isinstance(arg, str):
|
||||
args = [arg]
|
||||
else:
|
||||
args = list(arg)
|
||||
@ -473,7 +473,7 @@ class I2PHtmlFormatter(Formatter):
|
||||
return ', '.join(tmp)
|
||||
|
||||
styles = [(level, ttype, cls, style)
|
||||
for cls, (style, ttype, level) in self.class2style.iteritems()
|
||||
for cls, (style, ttype, level) in self.class2style.items()
|
||||
if cls and style]
|
||||
styles.sort()
|
||||
lines = ['%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:])
|
||||
@ -511,8 +511,8 @@ class I2PHtmlFormatter(Formatter):
|
||||
cssfilename = os.path.join(os.path.dirname(filename),
|
||||
self.cssfile)
|
||||
except AttributeError:
|
||||
print >>sys.stderr, 'Note: Cannot determine output file name, ' \
|
||||
'using current directory as base for the CSS file name'
|
||||
print('Note: Cannot determine output file name, ' \
|
||||
'using current directory as base for the CSS file name', file=sys.stderr)
|
||||
cssfilename = self.cssfile
|
||||
# write CSS file only if noclobber_cssfile isn't given as an option.
|
||||
try:
|
||||
@ -521,7 +521,7 @@ class I2PHtmlFormatter(Formatter):
|
||||
cf.write(CSSFILE_TEMPLATE %
|
||||
{'styledefs': self.get_style_defs('body')})
|
||||
cf.close()
|
||||
except IOError, err:
|
||||
except IOError as err:
|
||||
err.strerror = 'Error writing CSS file: ' + err.strerror
|
||||
raise
|
||||
|
||||
@ -540,7 +540,7 @@ class I2PHtmlFormatter(Formatter):
|
||||
yield 0, DOC_FOOTER
|
||||
|
||||
def _wrap_tablelinenos(self, inner):
|
||||
dummyoutfile = StringIO.StringIO()
|
||||
dummyoutfile = io.StringIO()
|
||||
lncount = 0
|
||||
for t, line in inner:
|
||||
if t:
|
||||
@ -884,7 +884,7 @@ class TextSpecFormatter(Formatter):
|
||||
else:
|
||||
outfile.write(value)
|
||||
|
||||
for ref in refs.values():
|
||||
for ref in list(refs.values()):
|
||||
if enc:
|
||||
outfile.write(ref.encode(enc))
|
||||
else:
|
||||
|
@ -56,7 +56,7 @@ class Pagination(object):
|
||||
def iter_pages(self, left_edge=2, left_current=2,
|
||||
right_current=5, right_edge=2):
|
||||
last = 0
|
||||
for num in xrange(1, self.pages + 1):
|
||||
for num in range(1, self.pages + 1):
|
||||
if num <= left_edge or \
|
||||
(num > self.page - left_current - 1 and \
|
||||
num < self.page + right_current) or \
|
||||
|
@ -197,7 +197,7 @@ LEGACY_RELEASES_MAP={
|
||||
'0.9.8': (2013, 9, 30),
|
||||
'0.9.8.1': (2013, 10, 2),
|
||||
'0.9.9': (2013, 12, 7),
|
||||
'0.9.10': (2014, 01, 22),
|
||||
'0.9.10': (2014, 0o1, 22),
|
||||
}
|
||||
|
||||
def legacy_show(f):
|
||||
@ -232,5 +232,6 @@ def legacy_release(version):
|
||||
else:
|
||||
return legacy_show('release-%s' % version)
|
||||
|
||||
def legacy_blog(lang, (year, month, day), title):
|
||||
def legacy_blog(lang, xxx_todo_changeme, title):
|
||||
(year, month, day) = xxx_todo_changeme
|
||||
return redirect(url_for('blog_post', lang=lang, slug=('%d/%02d/%02d/%s' % (year, month, day, title))), 301)
|
||||
|
@ -54,7 +54,7 @@ def get_meetings_ids(num=0):
|
||||
# iterate over all files
|
||||
for f in v[2]:
|
||||
# ignore all non-.rst files
|
||||
print("Meeting file found", f)
|
||||
print(("Meeting file found", f))
|
||||
if not f.endswith('.rst'):
|
||||
continue
|
||||
try:
|
||||
|
@ -33,7 +33,7 @@
|
||||
<img src="{{ url_for('static',
|
||||
filename='images/firefox57.connectionsettings.png') }}" alt="{{ _('Firefox57
|
||||
Connection Settings') }}" title="{{ _('Firefox57 Connection Settings') }}">
|
||||
<p>{% trans -%} Finally, go to the address <em>about:config</em> and find the property media.peerConnection.ice.proxy_only. Ensure that this setting is True. Now find the property keyword.enabled, and set it to False.{%- endtrans %}</p>
|
||||
<p>{% trans -%} Finally, go to the address <em>about:config</em> and find the property media.peerConnection.ice.proxy_only. Ensure that this setting is True. {%- endtrans %}</p>
|
||||
<img src="{{ url_for('static',
|
||||
filename='images/firefox.webrtc.png') }}" alt="{{ _('Firefox57
|
||||
PeerConnection Settings') }}" title="{{ _('Firefox57 PeerConnection Settings') }}">
|
||||
|
@ -12,7 +12,7 @@
|
||||
<li><a href="#debian">Knoppix</a></li>
|
||||
</ul>
|
||||
|
||||
{% trans gtitlab='https://i2pgit.org/I2P_Developers/i2p.i2p/' -%}
|
||||
{% trans gtitlab='https://i2pgit.org/i2p-hackers/i2p.i2p/' -%}
|
||||
The I2P packages <em>may</em> work on systems not listed above. Please report any issues
|
||||
with these packages on <a href="{{ gtitlab }}">Gitlab</a> at
|
||||
<a href="{{ gtitlab }}">i2p.i2p</a>.
|
||||
@ -86,11 +86,13 @@ part of <a href="#Post-install_work">starting I2P</a> and configuring it for you
|
||||
|
||||
<h2 id="debian">{{ _('Instructions for Debian') }}</h2>
|
||||
|
||||
<p><b>NOTICE:</b>
|
||||
Our old Debian repos <a href="https://deb.i2p2.de/">deb.i2p2.de</a> and
|
||||
<a href="http://deb.i2p2.no/">deb.i2p2.no</a> are EOL.
|
||||
Please follow <a href="https://deb.i2p.net">these instructions</a>
|
||||
to update to the new repository, <code>deb.i2p.net</code>.
|
||||
<p><b>WARNING:</b>
|
||||
Our Debian repos <a href="https://deb.i2p2.de/">deb.i2p2.de</a> and
|
||||
<a href="http://deb.i2p2.no/">deb.i2p2.no</a> are currently down, and probably will not be back soon.
|
||||
Please follow <a href="https://i2pforum.net/viewtopic.php?p=2855">these instructions</a>
|
||||
to use the Ubuntu PPA as a workaround.
|
||||
We will announce any updates here and on <a href="https://i2pforum.net/">i2pforum.net</a>.
|
||||
We apologize for the inconvenience.
|
||||
</p>
|
||||
|
||||
<em>{% trans -%}Currently supported architectures{%- endtrans %}: amd64, i386, armhf, arm64, powerpc, ppc64el, s390x</em>
|
||||
@ -114,7 +116,7 @@ user to root with <code>su</code> or by prefixing each command with <code>sudo</
|
||||
<pre>
|
||||
<code>
|
||||
# Use this command on Debian Bullseye or newer only.
|
||||
echo "deb [signed-by=/usr/share/keyrings/i2p-archive-keyring.gpg] https://deb.i2p.net/ $(lsb_release -sc) main" \
|
||||
echo "deb [signed-by=/usr/share/keyrings/i2p-archive-keyring.gpg] https://deb.i2p2.de/ $(lsb_release -sc) main" \
|
||||
| sudo tee /etc/apt/sources.list.d/i2p.list
|
||||
</code>
|
||||
</pre>
|
||||
@ -122,7 +124,7 @@ user to root with <code>su</code> or by prefixing each command with <code>sudo</
|
||||
<pre>
|
||||
<code>
|
||||
# Use this command on Debian Downstreams like LMDE or ParrotOS only.
|
||||
echo "deb [signed-by=/usr/share/keyrings/i2p-archive-keyring.gpg] https://deb.i2p.net/ $(dpkg --status tzdata | grep Provides | cut -f2 -d'-') main" \
|
||||
echo "deb [signed-by=/usr/share/keyrings/i2p-archive-keyring.gpg] https://deb.i2p2.de/ $(dpkg --status tzdata | grep Provides | cut -f2 -d'-') main" \
|
||||
| sudo tee /etc/apt/sources.list.d/i2p.list
|
||||
</code>
|
||||
</pre>
|
||||
@ -130,7 +132,7 @@ user to root with <code>su</code> or by prefixing each command with <code>sudo</
|
||||
<pre>
|
||||
<code>
|
||||
# Use this command on Debian Buster or older only.
|
||||
echo "deb https://deb.i2p.net/ $(lsb_release -sc) main" \
|
||||
echo "deb https://deb.i2p2.de/ $(lsb_release -sc) main" \
|
||||
| sudo tee /etc/apt/sources.list.d/i2p.list
|
||||
</code>
|
||||
</pre>
|
||||
@ -138,7 +140,7 @@ user to root with <code>su</code> or by prefixing each command with <code>sudo</
|
||||
<pre>
|
||||
<code>
|
||||
# Use this command on Debian Buster or older only.
|
||||
echo "deb https://deb.i2p.net/ $(dpkg --status tzdata | grep Provides | cut -f2 -d'-') main" \
|
||||
echo "deb https://deb.i2p2.de/ $(dpkg --status tzdata | grep Provides | cut -f2 -d'-') main" \
|
||||
| sudo tee /etc/apt/sources.list.d/i2p.list
|
||||
</code>
|
||||
</pre>
|
||||
|
@ -20,7 +20,7 @@ Please verify that the hashes match the downloads when installing the bundle.
|
||||
<h2>{{ _('What do I need to use it?') }}</h2>
|
||||
<p><strong>{% trans -%}
|
||||
Just Firefox (Or Tor Browser).{%- endtrans %}</strong>
|
||||
{% trans issueurl="https://i2pgit.org/I2P_Developers/i2p.firefox/-/issues/2" -%}
|
||||
{% trans issueurl="https://i2pgit.org/i2p-hackers/i2p.firefox/-/issues/2" -%}
|
||||
This installer still requires Firefox to be installed on the system, it does not
|
||||
bundle a Firefox installer of its own. Please obtain Firefox from Mozilla, or
|
||||
Tor Browser from the Tor Project or one of their mirrors. If you would like to
|
||||
@ -60,7 +60,7 @@ special configuration. You don't even need to close existing Firefox windows.
|
||||
{%- set name = 'Windows' -%}
|
||||
{%- set icon = 'images/download/windows.png' -%}
|
||||
{%- set filename = 'I2P-Easy-Install-Bundle-%s.exe' -%}
|
||||
{%- set hash = 'a8e7e02b00428a150d8287774879c3babd4f0eeede7b691403dc283c05bda750' -%}
|
||||
{%- set hash = 'def95180e5783686f68dcf2958cfa693f17a91da53a97f8ae75c98529c4e23a8' -%}
|
||||
|
||||
{% call package_outer('windows', name, icon) %}
|
||||
<div class = "file">
|
||||
@ -110,7 +110,7 @@ If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org or github.com. The license for each respective component
|
||||
can be found in the license directory of the <code>i2p.firefox</code> project.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/i2p/i2p.firefox">{% trans -%}Github Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/idk/i2p.plugins.firefox">{% trans -%}Gitlab Repository for Profile Manager{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/eyedeekay/i2p.plugins.firefox">{% trans -%}Github Repository Profile Manager{%- endtrans %}</a></div>
|
||||
@ -120,7 +120,7 @@ contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at least Reporter access"
|
||||
option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<h2>{{ _('How is it different from Tor Browser?') }}</h2>
|
||||
<p>{% trans -%}
|
||||
This is not a fork of Firefox. Instead, it is a browser profile with pre-configured
|
||||
|
@ -45,7 +45,7 @@ start an installer, "double-click" the downloaded .exe file.
|
||||
{%- set name = 'Windows' -%}
|
||||
{%- set icon = 'images/download/windows.png' -%}
|
||||
{%- set filename = 'I2P-Easy-Install-Bundle-%s.exe' -%}
|
||||
{%- set hash = 'a8e7e02b00428a150d8287774879c3babd4f0eeede7b691403dc283c05bda750' -%}
|
||||
{%- set hash = 'def95180e5783686f68dcf2958cfa693f17a91da53a97f8ae75c98529c4e23a8' -%}
|
||||
|
||||
{% call package_outer('windows', name, icon) %}
|
||||
<div class = "file">
|
||||
@ -87,7 +87,7 @@ If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org or github.com. The license for each respective component
|
||||
can be found in the license directory of the <code>i2p.firefox</code> project.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/i2p/i2p.firefox">{% trans -%}Github Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/idk/i2p.plugins.firefox">{% trans -%}Gitlab Repository for Profile Manager{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/eyedeekay/i2p.plugins.firefox">{% trans -%}Github Repository Profile Manager{%- endtrans %}</a></div>
|
||||
@ -97,7 +97,7 @@ contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at least Reporter access"
|
||||
option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<h2>{{ _('How is it different from Tor Browser?') }}</h2>
|
||||
<p>{% trans -%}
|
||||
This is not a fork of Firefox. Instead, it is a browser profile with pre-configured
|
||||
|
@ -57,14 +57,13 @@ If you would like to try the latest experimental I2P projects, visit the <a href
|
||||
{%- endtrans %}</p>
|
||||
<div class="file">
|
||||
<p></p>
|
||||
<a class="default" href="{{ get_url('downloads_macos') }}">{% trans %}Here is a helpful guide to installing I2P for Mac OS using a separate Java installation and the classic installer.{% endtrans %}</a>
|
||||
<a class="default" href="{{ get_url('downloads_mac') }}">{% trans %}Here is a helpful guide to installing I2P for Mac OS using a separate Java installation and the classic installer.{% endtrans %}</a>
|
||||
</div>
|
||||
{% endcall %}
|
||||
|
||||
|
||||
<h5>{%- trans %}I2P for Linux{%- endtrans %}</h5>
|
||||
{% call package('unix') %}
|
||||
|
||||
<p>{% trans i2pversion=ver() -%} The most reliable way to launch the installer is from a terminal like this:
|
||||
<code>java -jar i2pinstall_{{ i2pversion }}.jar</code>. This will launch the GUI installer. Depending on how your computer is set up, you may be able to start the installer by double-clicking the "i2pinstall_{{ i2pversion }}.jar" file
|
||||
or right-clicking the file and selecting "Open with Java". Unfortunately, this behaviour is difficult to predict. {%- endtrans %}</p>
|
||||
|
@ -113,13 +113,13 @@ I2P to launch when your user logs in by right-clicking on the I2P Dock icon.
|
||||
If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p-jpackage-mac">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p-jpackage-mac">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div>{% trans -%}
|
||||
If you wish to file an issue about the DMG Bundle, please use Gitlab to
|
||||
contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at
|
||||
least Reporter access" option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p-jpackage-mac/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p-jpackage-mac/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,16 +1,16 @@
|
||||
{% set i2pinstall_windows_hash = 'fe106319dcf5972b7c833150292cb72ae6a764cf18929f043dfb9f10340ee782' %}
|
||||
{% set i2pinstall_jar_hash = 'fee438e9f42345eeef3f5255842bbcf725eb01f1f84589791a525cd45143555b' %}
|
||||
{% set i2psource_hash = '03989319e186d9b06ed96ea0efa6ac95af1bc57af956d7f5f06f52f8da64fcd7' %}
|
||||
{% set i2pupdate_hash = '1b79b2593bbe60e08da3f84411d48a5f1fe0c8cfd934f1c90d2fece436c1f2b5' %}
|
||||
{% set i2p_android_hash = '13b6e3c35756605e8e65804ab91cb34521c819fcfaebafb348eba5d40bed6699' %}
|
||||
{% set i2pinstall_windows_hash = '2081f8415013c80daa6b69b6f16f2ebf10aa20ee3cace20936e0268b2e816a3f' %}
|
||||
{% set i2pinstall_jar_hash = '977ebce33001345731de6fe0b623f59a867de6fa6a6c46d8ad686e306310b28d' %}
|
||||
{% set i2psource_hash = 'a0a8fb08e9c72eaef22f155b9c9aa0ea90fb331d2bbcf76f82649f0b9efe5f5b' %}
|
||||
{% set i2pupdate_hash = '59b569dc17fad0e30e246048a3c275e403b308024eb88fda29ae83294bdbe8e6' %}
|
||||
{% set i2p_android_hash = '272acf543c4489dc3775c07c42eb91710b4ed377c78aff605e3d44e73fad5110' %}
|
||||
{% set i2p_macnative_hash = '18cb22cfcc3cbe0cec150e89a394d1a35703cb508ed627ef48084b7ba7c90dde' %}
|
||||
|
||||
{% set i2p_windows_subver = '' %}
|
||||
{% set i2p_macosx_launcher_version = '1.9.0' %}
|
||||
|
||||
{% set i2p_android_version = '2.9.0' %}
|
||||
{% set i2p_android_version = '2.2.1' %}
|
||||
{% set i2p_android_version_kytv = '0.9.22' %}
|
||||
{% set i2p_android_version_fdroid = '2.6.0' %}
|
||||
{% set i2p_android_version_fdroid = '2.2.1' %}
|
||||
|
||||
|
||||
{% macro package_outer(type, name, icon) -%}
|
||||
@ -80,8 +80,8 @@
|
||||
{%- if type == 'android' %}
|
||||
<!-- do not use url_for here -->
|
||||
<h3>{% trans %}Download I2P for {% endtrans %}{{name}}</h3>
|
||||
<a class="default" href="https://files.i2p-projekt.de/{{ i2p_android_version }}/app.apk">{% trans %}Outside I2P{% endtrans %} ({{ i2p_android_version }})</a>
|
||||
<a class="sig" href="https://files.i2p-projekt.de/{{ i2p_android_version }}/app.apk.asc">sig</a>
|
||||
<a class="default" href="https://download.i2p2.no/android/current/app.apk">{% trans %}Outside I2P{% endtrans %} ({{ i2p_android_version }})</a>
|
||||
<a class="sig" href="https://download.i2p2.no/android/current/app.apk.asc">sig</a>
|
||||
<!-- do not use i2pconv here -->
|
||||
<!--<a class="default" href="http://update.killyourtv.i2p/i2p.apk">{% trans %}Inside I2P{% endtrans %} ({{ i2p_android_version_kytv }})</a> -->
|
||||
<a class="default" href="https://play.google.com/store/apps/details?id=net.i2p.android">Google Play ({{ i2p_android_version }})</a>
|
||||
|
@ -31,35 +31,6 @@
|
||||
#
|
||||
# Proposed new sections: application privacy, data anonymization, ...
|
||||
#
|
||||
@inproceedings {abdo,
|
||||
author = {Jacques Bou Abdo and Liaquat Hossain},
|
||||
title = {Modeling the Invisible Internet},
|
||||
booktitle = {Complex Networks and their Applications XII},
|
||||
year = {2024},
|
||||
url = {https://link.springer.com/chapter/10.1007/978-3-031-53472-0_30},
|
||||
publisher = {Springer},
|
||||
month = {February},
|
||||
www_section = traffic,
|
||||
}
|
||||
|
||||
@techreport{stickland2021,
|
||||
title = {Foundations of Rigorous Cyber Experimentation},
|
||||
author = {Michael Stickland and Justin D. Li and Laura Swiler and Thomas Tarman},
|
||||
institution = {Sandia National Laboratories},
|
||||
year = {2021},
|
||||
month = {September},
|
||||
url = {https://www.osti.gov/servlets/purl/1854751/},
|
||||
www_section = traffic,
|
||||
}
|
||||
|
||||
@phdthesis{yu2021,
|
||||
title = {Research and implementation of bridge technology in I2P anonymous system},
|
||||
author = {Yu Chih-Wei},
|
||||
school = {Beijing University of Posts and Telecommunications},
|
||||
year = {2021},
|
||||
url = {https://www.zhangqiaokeyan.com/academic-degree-domestic_mphd_thesis/020318030805.html},
|
||||
www_section = comm,
|
||||
}
|
||||
|
||||
@article {qu2020,
|
||||
author = {QU Yun-xuan and WANG Yi-jun and XUE Zhi},
|
||||
@ -291,16 +262,6 @@ on our factors and measure the level of anonymity.}},
|
||||
www_section = comm,
|
||||
}
|
||||
|
||||
@inproceedings{jeong2016,
|
||||
title = {A Longitudinal Analysis of .i2p Leakage in the Public DNS Infrastructure},
|
||||
author = {Seong Hoon Jeong and Ah Reum Kang and Joongheon Kim and Huy Kang Kim2 and Aziz Mohaisen},
|
||||
booktitle = {SIGCOMM 2016 August 22-26, Florianopolis, Brazil},
|
||||
year = {2016},
|
||||
month = {August},
|
||||
www_pdf_url = {https://www.cs.ucf.edu/~mohaisen/doc/sigcomm16.pdf},
|
||||
www_section = comm,
|
||||
}
|
||||
|
||||
#
|
||||
# Actually a bachelors thesis but there's no @ for that
|
||||
#
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('Presentations on I2P') }}{% endblock %}
|
||||
{% block lastupdated %}2024-09{% endblock %}
|
||||
{% block lastupdated %}2022-03{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans papers=site_url('papers') -%}
|
||||
Following are links to presentations, videos, and tutorials about I2P. Links to research papers on I2P are available <a href="{{ papers }}">here</a>.
|
||||
@ -139,25 +139,6 @@ Andrew Savchenko (bircoph), FOSDEM, Brussel, February 4, 2018
|
||||
idk
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>
|
||||
I2P, blockchain and the application (FOSDEM 2021)
|
||||
<a href="https://odysee.com/@diva.exchange:d/diva-exchange-fosdem-21:c">video</a>
|
||||
February 7, 2021
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Private, fully distributed exchange (DEX), Monero and I2P research results
|
||||
<a href="https://odysee.com/@diva.exchange:d/monerokon2022:0">video</a>
|
||||
MoneroKon 2022 Lisbon
|
||||
July 5, 2022
|
||||
</li>
|
||||
|
||||
<li>
|
||||
DNS for I2P (FOSDEM 2023)
|
||||
<a href="https://odysee.com/@diva.exchange:d/diva-dns-i2p-fosdem2023:2">video</a>
|
||||
February 12, 2023
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
@ -283,33 +264,6 @@ Opt Out Podcast Season 2 Episode 10
|
||||
March 6, 2022
|
||||
</li>
|
||||
|
||||
<li>
|
||||
I2P and DIVA.EXCHANGE - Interview with Konrad
|
||||
(<a href="https://odysee.com/@diva.exchange:d/i2p-diva-exchange-2022-09-26:6">video</a>)
|
||||
September 26, 2022
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Interview with Sadie on I2P and the Free Internet
|
||||
(<a href="https://www.diva.exchange/en/privacy/i2p-and-the-free-internet-interview-with-a-community-member/">interview</a>)
|
||||
February 2024
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Interview with Phillip on I2P Network Reliability
|
||||
(<a href="https://www.diva.exchange/en/privacy/i2p-network-reliability-is-on-the-radar-of-the-academic-community/">interview</a>)
|
||||
March 2024
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Interview with IDK on I2P Development
|
||||
(<a href="https://www.diva.exchange/en/privacy/i2p-interview-with-the-developer-idk-part-1/">interview part 1</a>)
|
||||
July 2024;
|
||||
(<a href="https://www.diva.exchange/en/privacy/i2p-interview-with-the-developer-idk-part-2/">interview part 2</a>)
|
||||
September 2024
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>{{ _('Other') }}</h2>
|
||||
|
@ -1,6 +1,5 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('Strict Countries') }}{% endblock %}
|
||||
{% block lastupdated %}2024-07{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans -%}This implementation of I2P (the Java implementation distributed on this site)
|
||||
includes a "Strict Countries List" which we use to decide how routers should behave
|
||||
@ -17,14 +16,14 @@ guidance is to include countries with a Civil Liberties (CL) score of 16 or less
|
||||
Freedom score of 39 or less (not free).{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans -%}Hidden Mode Summary{%- endtrans %}</h4>
|
||||
<p>{% trans -%}When a router is placed into hidden mode, three key things change about its behavior.
|
||||
<p>{% trans -%}When a router is placed into hidden mode, three key things change about it's behavior.
|
||||
It will no longer publish a routerInfo to the NetDB, it will no longer accept
|
||||
participating tunnels, and it will reject direct connections to routers in the same
|
||||
country that it is in. These defenses make the routers more difficult to enumerate
|
||||
reliably, and prevent them from running afoul of restrictions on routing traffic for
|
||||
others.{%- endtrans %}</p>
|
||||
|
||||
<h4>{% trans -%}Strict Countries List as of 2024{%- endtrans %}</h4>
|
||||
<h4>{% trans -%}Strict Countries List as of 2020{%- endtrans %}</h4>
|
||||
<pre><code>
|
||||
/* Afghanistan */ "AF",
|
||||
/* Azerbaijan */ "AZ",
|
||||
|
@ -30,7 +30,7 @@ The following are discussed on the <a href="{{ othernetworks }}">other networks
|
||||
<li>Haystack</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
The content of this page is subject to update, discussion and dispute, and we welcome comments and additions.
|
||||
You may contribute an analysis by entering a <a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
@ -14,7 +14,7 @@ The following networks are discussed on this page.
|
||||
<li>Haystack</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans comparison=site_url('comparison'), trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans comparison=site_url('comparison'), trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
Most of the following sections are fairly old, and may not be accurate.
|
||||
For an overview of available comparisons, see the
|
||||
<a href="{{ comparison }}">main network comparisons page</a>.
|
||||
@ -246,13 +246,13 @@ I2P is, of course, open source. However, that source, and our
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{{ _('Paid VPN Services') }}</h2>
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
You may contribute an analysis by entering a
|
||||
<a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{{ _('Others') }}</h2>
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
You may contribute an analysis by entering a
|
||||
<a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
@ -1,20 +1,18 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('BOB - Basic Open Bridge') }}{% endblock %}
|
||||
{% block lastupdated %}2025-05{% endblock %}
|
||||
{% block lastupdated %}2022-06{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Warning - Deprecated</h2>
|
||||
<p>Not for use by new applications.
|
||||
BOB, as specified here, supports the DSA-SHA1 signature type only.
|
||||
BOB supports the DSA-SHA1 signature type only.
|
||||
BOB will not be extended to support new signature types or other advanced features.
|
||||
New applications should use <a href="{{ site_url('docs/api/samv3') }}">SAM V3</a>.
|
||||
</p><p>
|
||||
BOB support was removed from Java I2P new installs as of release 1.7.0 (2022-02).
|
||||
BOB is not supported in Java I2P new installs as of release 1.7.0 (2022-02).
|
||||
It will still work in Java I2P originally installed as version 1.6.1 or earlier,
|
||||
even after updates, but it is unsupported and may break at any time.
|
||||
BOB is still supported by i2pd as of 2025-05, but applications
|
||||
BOB is still supported by i2pd as of 2022-06, but applications
|
||||
should still migrate to SAMv3 for the reasons above.
|
||||
See <a href="https://i2pd.readthedocs.io/en/latest/devs/i2pd-specifics/">the i2pd documentation</a>
|
||||
for any extensions to the API documented here that are supported by i2pd.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Datagrams{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2025-04{% endblock %}
|
||||
{% block accuratefor %}0.9.66{% endblock %}
|
||||
{% block lastupdated %}{% trans %}February 2019{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.9.39{% endblock %}
|
||||
{% block content %}
|
||||
<h2>{% trans %}Datagram Overview{% endtrans %}</h2>
|
||||
<p>{% trans i2cp=site_url('docs/protocol/i2cp') -%}
|
||||
@ -35,30 +35,30 @@ the 'streamr' tunnel types, and udpTunnel classes.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Datagram Length{% endtrans %}</h3>
|
||||
<p>
|
||||
<p>{% trans -%}
|
||||
The application designer should carefully consider the tradeoff of repliable vs. non-repliable
|
||||
datagrams. Also, the datagram size will affect reliability, due to tunnel fragmentation into 1KB
|
||||
tunnel messages. The more message fragments, the more likely that one of them will be dropped
|
||||
by an intermediate hop. Messages larger than a few KB are not recommended.
|
||||
Over about 10 KB, the delivery probablility drops dramatically.
|
||||
</p>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}">{% trans -%}
|
||||
See the Datagrams Specification page.
|
||||
{%- endtrans %}</a>
|
||||
Messages over 16 KB cannot be delivered over NTCP, dropping delivery chances even more.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<p>
|
||||
Also note that the various overheads added by lower layers, in particular
|
||||
garlic messages, place a large burden on intermittent messages
|
||||
<p>{% trans elgamalaes=site_url('docs/how/elgamal-aes') -%}
|
||||
Also note that the various overheads added by lower layers, in particular asymmetric
|
||||
<a href="{{ elgamalaes }}">ElGamal/AES</a>, place a large burden on intermittent messages
|
||||
such as used by a Kademlia-over-UDP application. The implementations are currently tuned
|
||||
for frequent traffic using the streaming library.
|
||||
</p>
|
||||
for frequent traffic using the streaming library. There are a high number
|
||||
of session tags delivered, and a short session tag lifetime, for example.
|
||||
There are currently no configuration parameters available within I2CP to tune
|
||||
the ElGamal Session Tag parameters.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}I2CP Protocol Number and Ports{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The standard I2CP protocol number for signed (repliable) datagrams is PROTO_DATAGRAM (17).
|
||||
The standard I2CP protocol number for datagrams is PROTO_DATAGRAM (17).
|
||||
Applications may or may not choose to set the
|
||||
protocol in the I2CP header. The default is implementation-dependent.
|
||||
protocol in the I2CP header. It is not set by default.
|
||||
It must be set to demultiplex datagram and streaming traffic received on the same Destination.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
@ -75,8 +75,7 @@ There is no method within the datagram API to specify whether it is non-repliabl
|
||||
or repliable. The application should be designed to expect the appropriate type.
|
||||
The I2CP protocol number or port should be used by the application to
|
||||
indicate datagram type.
|
||||
The I2CP protocol numbers PROTO_DATAGRAM (signed, also known as Datagram1), PROTO_DATAGRAM_RAW,
|
||||
PROTO_DATAGRAM2, and PROTO_DATAGRAM3 are defined in the
|
||||
The I2CP protocol numbers PROTO_DATAGRAM (signed) and PROTO_DATAGRAM_RAW are defined in the
|
||||
<a href="{{ i2psession }}">I2PSession API</a>
|
||||
for this purpose. A common design pattern in client/server datagram applications is to
|
||||
use signed datagrams for a request which includes a nonce, and use a raw datagram
|
||||
@ -87,10 +86,6 @@ for the reply, returning the nonce from the request.
|
||||
PROTO_DATAGRAM = 17
|
||||
</li><li>
|
||||
PROTO_DATAGRAM_RAW = 18
|
||||
</li><li>
|
||||
PROTO_DATAGRAM2 = 19
|
||||
</li><li>
|
||||
PROTO_DATAGRAM3 = 20
|
||||
</li></ul>
|
||||
|
||||
<p>{% trans i2psession='http://'+i2pconv('idk.i2p/javadoc-i2p')+'/net/i2p/client/I2PSession.html',
|
||||
@ -105,7 +100,6 @@ as implemented in
|
||||
<p>{% trans i2cp=site_url('docs/protocol/i2cp') -%}
|
||||
Data integrity is assured by the gzip CRC-32 checksum implemented in
|
||||
<a href="{{ i2cp }}#format">the I2CP layer</a>.
|
||||
Authenticated datagrams (Datagram1 and Datagram2) also ensure integrity.
|
||||
There is no checksum field in the datagram protocol.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V1 Specification{% endblock %}
|
||||
{% block lastupdated %}2025-03{% endblock %}
|
||||
{% block lastupdated %}May 2015{% endblock %}
|
||||
{% block accuratefor %}0.9.20{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Warning - Deprecated - Unsupported - Use <a href="samv3.html">SAMv3</a></h2>
|
||||
<p>Specified below is version 1 of a simple client protocol for interacting with
|
||||
I2P.
|
||||
Newer alternatives:
|
||||
|
@ -1,10 +1,9 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V2 Specification{% endblock %}
|
||||
{% block lastupdated %}2025-03{% endblock %}
|
||||
{% block lastupdated %}May 2015{% endblock %}
|
||||
{% block accuratefor %}0.9.20{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Warning - Deprecated - Unsupported - Use <a href="samv3.html">SAMv3</a></h2>
|
||||
<p>Specified below is version 2 of a simple client protocol for interacting with I2P.
|
||||
<p>Specified below is a simple client protocol for interacting with I2P.
|
||||
</p>
|
||||
<p>
|
||||
SAM V2 was introduced in I2P release 0.6.1.31.
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}SAM V3{% endblock %}
|
||||
{% block lastupdated %}2025-04{% endblock %}
|
||||
{% block accuratefor %}API 0.9.66{% endblock %}
|
||||
{% block lastupdated %}2023-11{% endblock %}
|
||||
{% block accuratefor %}API 0.9.59{% endblock %}
|
||||
{% block content %}
|
||||
<p>SAM is a simple client protocol for interacting with I2P.
|
||||
SAM is the recommended protocol for non-Java applications to connect to the I2P network,
|
||||
@ -77,16 +77,7 @@ Do your own research.
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td><a href="https://github.com/eyedeekay/sam3">github.com/eyedeekay/sam3</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>onramp</td>
|
||||
<td>Go</td>
|
||||
<td>3.3</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td><a href="https://github.com/eyedeekay/onramp">github.com/eyedeekay/onramp</a></td>
|
||||
<td><a href="https://bitbucket.org/eyedeekay/sam3">bitbucket.org/eyedeekay/sam3</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>txi2p</td>
|
||||
@ -158,7 +149,7 @@ Do your own research.
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td><a href="https://notabug.org/villain/mooni2p">notabug.org/villain/mooni2p</a></td>
|
||||
<td><a href="https://notabug.org/l-n-s/mooni2p">notabug.org/l-n-s/mooni2p</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>haskell-network-anonymous-i2p</td>
|
||||
@ -233,13 +224,13 @@ Do your own research.
|
||||
<td><a href="https://github.com/syvita/solitude">github.com/syvita/solitude</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Samty</td>
|
||||
<td>i2pSAM-Qt</td>
|
||||
<td>C++</td>
|
||||
<td>3.1</td>
|
||||
<td>yes</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><a href="https://notabug.org/acetone/samty">notabug.org/acetone/samty</a></td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
<td><a href="https://notabug.org/acetone/i2pSAM-Qt">notabug.org/acetone/i2pSAM-Qt</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>bitcoin</td>
|
||||
@ -261,7 +252,7 @@ To implement a basic TCP-only, peer-to-peer application, the client must support
|
||||
<li> HELLO VERSION MIN=3.1 MAX=3.1 <br> Needed for all of the remaining ones
|
||||
<li> DEST GENERATE SIGNATURE_TYPE=7 <br> To generate our private key and destination
|
||||
<li> NAMING LOOKUP NAME=... <br> To convert .i2p addresses to destinations
|
||||
<li> SESSION CREATE STYLE=STREAM ID=... DESTINATION=... i2cp.leaseSetEncType=4,0<br> Needed for STREAM CONNECT and STREAM ACCEPT
|
||||
<li> SESSION CREATE STYLE=STREAM ID=... DESTINATION=... <br> Needed for STREAM CONNECT and STREAM ACCEPT
|
||||
<li> STREAM CONNECT ID=... DESTINATION=... <br> To make outgoing connections
|
||||
<li> STREAM ACCEPT ID=... <br> To accept incoming connections
|
||||
</ul>
|
||||
@ -269,7 +260,6 @@ To implement a basic TCP-only, peer-to-peer application, the client must support
|
||||
|
||||
|
||||
<h2>General Guidance for Developers</h2>
|
||||
<h3>Application Design</h3>
|
||||
<p>
|
||||
SAM sessions (or inside I2P, tunnel pools or sets of tunnels) are designed to be long-lived.
|
||||
Most applications will only need one session, created at startup and closed on exit.
|
||||
@ -283,9 +273,7 @@ Also, please ensure your application settings
|
||||
will result in your users contributing more resources to the network than they consume.
|
||||
I2P is a peer-to-peer network, and the network cannot survive if a popular application
|
||||
drives the network into permanent congestion.
|
||||
</p>
|
||||
<h3>Compatibility and Testing</h3>
|
||||
<p>
|
||||
</p><p>
|
||||
The Java I2P and i2pd router implementations are independent and have minor differences
|
||||
in behavior, feature support, and defaults.
|
||||
Please test your application with the latest version of both routers.
|
||||
@ -306,20 +294,8 @@ See below.
|
||||
For more guidance to developers on ensuring your application uses only the resources it needs, please see
|
||||
<a href="{{ site_url('docs/applications/embedding') }}">our guide to bundling I2P with your application</a>.
|
||||
</p>
|
||||
<h3>Signature and Encryption Types</h3>
|
||||
<p>
|
||||
I2P supports multiple signature and encryption types.
|
||||
For backward compatibility, SAM defaults to old and inefficient types, so all clients should
|
||||
specify newer types.
|
||||
</p><p>
|
||||
The signature type is specified in the DEST GENERATE and SESSION CREATE (for transient) commands.
|
||||
All clients should set SIGNATURE_TYPE=7 (Ed25519).
|
||||
</p><p>
|
||||
The encryption type is specified in the SESSION CREATE command.
|
||||
Multiple encryption types are allowed.
|
||||
Clients should set either i2cp.leaseSetEncType=4 (for ECIES-X25519 only)
|
||||
or i2cp.leaseSetEncType=4,0 (for ECIES-X25519 and ElGamal, if compatibility is required).
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>Version 3 Changes</h2>
|
||||
@ -433,18 +409,14 @@ As of SAM 3.2, optional authentication user/password parameters are supported in
|
||||
and may be required by the bridge.
|
||||
|
||||
</p><p>
|
||||
I2P communications can take several distinct forms:
|
||||
I2P communications can take three distinct forms:
|
||||
<ul><li>
|
||||
<a href="{{ site_url('docs/api/streaming') }}">Virtual streams</a>
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}#repliable">Repliable and authenticated datagrams</a> (messages with a FROM field)
|
||||
</li><li>
|
||||
</lil><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}#repliable">Repliable datagrams</a> (messages with a FROM field)
|
||||
</lil><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}#raw">Anonymous datagrams</a> (raw anonymous messages)
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}#datagram2">Datagram2</a> (a new repliable and authenticated format)
|
||||
</li><li>
|
||||
<a href="{{ site_url('docs/spec/datagrams') }}#datagram3">Datagram3</a> (a new repliable but unauthenticated format)
|
||||
</li></ul>
|
||||
</lil></ul>
|
||||
</p><p>
|
||||
I2P communications are supported by I2P sessions, and each I2P
|
||||
session is bound to an address (called destination). An I2P session
|
||||
@ -669,18 +641,18 @@ received through other forms are answered with an error message) :
|
||||
|
||||
<pre>
|
||||
-> SESSION CREATE
|
||||
STYLE={STREAM,DATAGRAM,RAW,DATAGRAM2,DATAGRAM3} # See below for DATAGRAM2/3
|
||||
STYLE={STREAM,DATAGRAM,RAW}
|
||||
ID=$nickname
|
||||
DESTINATION={$privkey,TRANSIENT}
|
||||
[SIGNATURE_TYPE=value] # SAM 3.1 or higher only, for DESTINATION=TRANSIENT only, default DSA_SHA1
|
||||
[PORT=$port] # Required for DATAGRAM* RAW, invalid for STREAM
|
||||
[HOST=$host] # Optional for DATAGRAM* and RAW, invalid for STREAM
|
||||
[PORT=$port] # Required for DATAGRAM and RAW, invalid for STREAM
|
||||
[HOST=$host] # Optional for DATAGRAM and RAW, invalid for STREAM
|
||||
[FROM_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[TO_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, for STYLE=RAW only, default 18
|
||||
[HEADER={true,false}] # SAM 3.2 or higher only, for STYLE=RAW only, default false
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, DATAGRAM*/RAW only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, DATAGRAM*/RAW only, default 7655
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, DATAGRAM/RAW only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, DATAGRAM/RAW only, default 7655
|
||||
[option=value]* # I2CP and streaming options
|
||||
</pre>
|
||||
|
||||
@ -870,7 +842,7 @@ depending on signature type.
|
||||
<b>NOTE:</b>
|
||||
Since about 2014 (SAM v3.1), Java I2P has also supported hostnames and b32 addresses for the $destination, but this was previously undocumented.
|
||||
Hostnames and b32 addresses are now officially supported by Java I2P as of release 0.9.48.
|
||||
The i2pd router supports hostnames and b32 addresses as of release 2.38.0 (0.9.50).
|
||||
The i2pd router will support hostnames and b32 addresses as of release 2.38.0 (0.9.50).
|
||||
For both routers, "b32" support includes support extended "b33" addresses for blinded destinations.
|
||||
</p>
|
||||
|
||||
@ -1136,19 +1108,15 @@ SAMv3 provides mechanisms to send and receive datagrams over local datagram sock
|
||||
Some SAMv3 implementations also support the older v1/v2 way of sending/receiving
|
||||
datagrams over the SAM bridge socket. Both are documented below.
|
||||
</p><p>
|
||||
I2P supports four types of datagrams:
|
||||
I2P supports two types of datagrams:
|
||||
</p>
|
||||
<ul><li>
|
||||
Repliable and authenticated datagrams are prefixed with the destination of the sender,
|
||||
"Repliable" datagrams are prefixed with the destination of the sender,
|
||||
and contain the signature of the sender, so the receiver
|
||||
may verify that the sender's destination was not spoofed,
|
||||
and may reply to the datagram.
|
||||
The new Datagram2 format is also repliable and authenticated.
|
||||
</li><li>
|
||||
The new Datagram3 format is repliable but not authenticated.
|
||||
The sender information is unverified.
|
||||
</li><li>
|
||||
Raw datagrams do not contain the destination of the sender or a signature.
|
||||
"Raw" datagrams do not contain the destination of the sender or a signature.
|
||||
</li></ul>
|
||||
<p>
|
||||
Default I2CP ports are defined for both repliable and raw datagrams.
|
||||
@ -1255,7 +1223,7 @@ message:
|
||||
|
||||
<pre>
|
||||
<- DATAGRAM RECEIVED
|
||||
DESTINATION=$destination # See notes below for Datagram3 format
|
||||
DESTINATION=$destination
|
||||
SIZE=$numBytes
|
||||
FROM_PORT=nnn # SAM 3.2 or higher only
|
||||
TO_PORT=nnn # SAM 3.2 or higher only
|
||||
@ -1283,7 +1251,7 @@ CREATE command with PORT and HOST options:
|
||||
|
||||
<pre>
|
||||
-> SESSION CREATE
|
||||
STYLE={DATAGRAM,RAW,DATAGRAM2,DATAGRAM3} # See below for DATAGRAM2/3
|
||||
STYLE={DATAGRAM,RAW}
|
||||
ID=$nickname
|
||||
DESTINATION={$privkey,TRANSIENT}
|
||||
PORT=$port
|
||||
@ -1306,9 +1274,8 @@ CREATE command with PORT and HOST options:
|
||||
The binary format is specified in <a href="http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/PrivateKeyFile.html">Private Key File</a>.
|
||||
|
||||
</p><p>
|
||||
Offline signatures are supported for RAW, DATAGRAM2, and DATAGRAM3 datagrams,
|
||||
but not for DATAGRAM.
|
||||
See the SESSION CREATE section above and the DATAGRAM2/3 section below for details.
|
||||
Offline signatures are only supported for RAW datagrams.
|
||||
See the SESSION CREATE section above for details.
|
||||
|
||||
</p><p>
|
||||
$host is the hostname or IP address of the datagram server to
|
||||
@ -1327,13 +1294,12 @@ configuration if not interpreted by the SAM bridge (e.g.
|
||||
outbound.length=0). These options <a href="#options">are documented below</a>.
|
||||
|
||||
</p><p>
|
||||
Forwarded repliable datagrams are always prefixed with the base64 destination,
|
||||
except for Datagram3, see below.
|
||||
Forwarded repliable datagrams are always prefixed with the destination.
|
||||
When a repliable datagram arrives, the bridge sends to the specified host:port
|
||||
a UDP packet containing the following data:
|
||||
|
||||
<pre>
|
||||
$destination # See notes below for Datagram3 format
|
||||
$destination
|
||||
FROM_PORT=nnn # SAM 3.2 or higher only
|
||||
TO_PORT=nnn # SAM 3.2 or higher only
|
||||
\n
|
||||
@ -1429,54 +1395,6 @@ the forwarded raw datagram will be prepended with a header line as follows:
|
||||
For an alternate method of sending anonymous datagrams, see <a href="#dgsend">RAW SEND</a>.
|
||||
</p>
|
||||
|
||||
<h4>Datagram 2/3</h4>
|
||||
|
||||
<p>
|
||||
Datagram 2/3 are new formats specified in early 2025.
|
||||
No known implementations currently exist.
|
||||
Check implementation documentation for current status.
|
||||
See <a href="{{ site_url('docs/spec/datagrams') }}">the specification</a> for more information.
|
||||
|
||||
</p><p>
|
||||
There are no current plans to increase the SAM version to indicate Datagram 2/3 support.
|
||||
This may be problematic as implementations may wish to support Datagram 2/3
|
||||
but not SAM v3.3 features.
|
||||
Any version change is TBD.
|
||||
|
||||
</p><p>
|
||||
Both Datagram2 and Datagram3 are repliable. Only Datagram2 is authenticated.
|
||||
|
||||
</p><p>
|
||||
Datagram2 is identical to repliable datagrams from a SAM perspective..
|
||||
Both are authenticated.
|
||||
Only the I2CP format and signature are different, but this is not visible
|
||||
to SAM clients.
|
||||
Datagram2 also supports offline signatures, so it may be used
|
||||
by offline-signed destinations.
|
||||
|
||||
</p><p>
|
||||
The intention is for Datagram2 to replace Repliable datagrams
|
||||
for new applications that do not require backward-compatibility.
|
||||
Datagram2 provides replay protection that is not present for Repliable datagrams.
|
||||
If backward-compatibility is required, an application may support
|
||||
both Datagram2 and Repliable may be supported on the same
|
||||
session with SAM 3.3 PRIMARY sessions.
|
||||
|
||||
</p><p>
|
||||
Datagram3 is repliable but not authenticated.
|
||||
The 'from' field in the I2CP format is a hash, not a destination.
|
||||
The $destination as sent from the SAM server to the client
|
||||
will be a 44-byte base64 hash.
|
||||
To convert it to a full destination for reply,
|
||||
base64-decode it to 32 bytes binary, then base32-encode it to 52 characters
|
||||
and append ".b32.i2p" for a NAMING LOOKUP.
|
||||
As usual, clients should maintain their own cache to avoid repeated NAMING LOOKUPs.
|
||||
|
||||
</p><p>
|
||||
Application designers should use extreme caution and consider the security implications
|
||||
of unauthenticated datagrams.
|
||||
|
||||
</p>
|
||||
|
||||
<h4>V3 Datagram MTU Considerations</h4>
|
||||
<p>
|
||||
@ -1523,10 +1441,6 @@ These commands do <i>not</i> support the ID parameter. The datagrams are
|
||||
sent to the most recently created DATAGRAM- or RAW-style session,
|
||||
as appropriate. Support for the ID parameter may be added in a future release.
|
||||
|
||||
</p><p>
|
||||
DATAGRAM2 and DATAGRAM3 formats are <i>not</i> supported
|
||||
in the V1/V2 compatible way.
|
||||
|
||||
|
||||
<h3 id="primary">SAM PRIMARY Sessions (V3.3 and higher)</h3>
|
||||
|
||||
@ -1603,10 +1517,10 @@ Using the same control socket on which the PRIMARY session was created:
|
||||
|
||||
<pre>
|
||||
-> SESSION ADD
|
||||
STYLE={STREAM,DATAGRAM,RAW,DATAGRAM2,DATAGRAM3} # See above for DATAGRAM2/3
|
||||
STYLE={STREAM,DATAGRAM,RAW}
|
||||
ID=$nickname # must be unique
|
||||
[PORT=$port] # Required for DATAGRAM* and RAW, invalid for STREAM
|
||||
[HOST=$host] # Optional for DATAGRAM* and RAW, invalid for STREAM
|
||||
[PORT=$port] # Required for DATAGRAM and RAW, invalid for STREAM
|
||||
[HOST=$host] # Optional for DATAGRAM and RAW, invalid for STREAM
|
||||
[FROM_PORT=nnn] # For outbound traffic, default 0
|
||||
[TO_PORT=nnn] # For outbound traffic, default 0
|
||||
[PROTOCOL=nnn] # For outbound traffic for STYLE=RAW only, default 18
|
||||
@ -1615,8 +1529,8 @@ Using the same control socket on which the PRIMARY session was created:
|
||||
[LISTEN_PROTOCOL=nnn] # For inbound traffic for STYLE=RAW only.
|
||||
# Default is the PROTOCOL value; 6 (streaming) is disallowed
|
||||
[HEADER={true,false}] # For STYLE=RAW only, default false
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, DATAGRAM*/RAW only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, DATAGRAM*/RAW only, default 7655
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, DATAGRAM/RAW only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, DATAGRAM/RAW only, default 7655
|
||||
[option=value]* # I2CP and streaming options
|
||||
</pre>
|
||||
|
||||
@ -1693,7 +1607,6 @@ bridge for name resolution:
|
||||
<pre>
|
||||
NAMING LOOKUP
|
||||
NAME=$name
|
||||
[OPTIONS=true] # Default false, as of router API 0.9.66
|
||||
</pre>
|
||||
|
||||
</p><p>
|
||||
@ -1705,7 +1618,6 @@ which is answered by
|
||||
NAME=$name
|
||||
[VALUE=$destination]
|
||||
[MESSAGE="$message"]
|
||||
[OPTION:optionkey="$optionvalue"] # As of router API 0.9.66
|
||||
</pre>
|
||||
|
||||
|
||||
@ -1737,35 +1649,6 @@ However, in some implementations, a .b32.i2p lookup which is uncached and requir
|
||||
a network query may fail, as no client tunnels are available for the lookup.
|
||||
</p>
|
||||
|
||||
<h4>Name Lookup Options</h4>
|
||||
<p>
|
||||
NAMING LOOKUP is extended as of router API 0.9.66 to support service lookups.
|
||||
Support may vary by implementation.
|
||||
See proposal 167 for additional information.
|
||||
|
||||
</p><p>
|
||||
NAMING LOOKUP NAME=example.i2p OPTIONS=true requests the options mapping in the reply.
|
||||
NAME may be a full base64 destination when OPTIONS=true.
|
||||
|
||||
</p><p>
|
||||
If the destination lookup was successful and options were present in the leaseset,
|
||||
then in the reply, following the destination,
|
||||
will be one or more options in the form of OPTION:key=value.
|
||||
Each option will have a separate OPTION: prefix.
|
||||
All options from the leaseset will be included, not just service record options.
|
||||
For example, options for parameters defined in the future may be present.
|
||||
Example:
|
||||
|
||||
</p><p>
|
||||
NAMING REPLY RESULT=OK NAME=example.i2p VALUE=base64dest OPTION:_smtp._tcp="1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
|
||||
|
||||
</p><p>
|
||||
Keys containing '=', and keys or values containing a newline,
|
||||
are considered invalid and the key/value pair will be removed from the reply.
|
||||
If there are no options found in the leaseset, or if the leaseset was version 1,
|
||||
then the response will not include any options.
|
||||
If OPTIONS=true was in the lookup, and the leaseset is not found, a new result value LEASESET_NOT_FOUND will be returned.
|
||||
</p>
|
||||
|
||||
<h4>Destination Key Generation</h4>
|
||||
</p><p>
|
||||
@ -1923,25 +1806,8 @@ their meaning:
|
||||
KEY_NOT_FOUND The naming system can't resolve the given name
|
||||
PEER_NOT_FOUND The peer cannot be found on the network
|
||||
TIMEOUT Timeout while waiting for an event (e.g. peer answer)
|
||||
LEASESET_NOT_FOUND See Name Lookup Options above. As of router API 0.9.66.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Different implementations may not be consistent in which RESULT is returned
|
||||
in various scenarios.
|
||||
|
||||
<p>
|
||||
Most responses with a RESULT, other than OK, will also include a MESSAGE with additional information.
|
||||
The MESSAGE will generally be helpful in debugging problems.
|
||||
However, MESSAGE strings are implementation-dependent,
|
||||
may or may not be translated by the SAM server to the current locale,
|
||||
may contain internal implementation-specific information such as exceptions,
|
||||
and are subject to change without notice.
|
||||
While SAM clients may choose to expose MESSAGE strings to users,
|
||||
they should not make programmatic decisions based on those strings,
|
||||
as that will be fragile.
|
||||
|
||||
|
||||
|
||||
<h3 id="options">Tunnel, I2CP, and Streaming Options</h3>
|
||||
<p>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Streaming Protocol{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-09{% endblock %}
|
||||
{% block accuratefor %}0.9.64{% endblock %}
|
||||
{% block lastupdated %}2022-04{% endblock %}
|
||||
{% block accuratefor %}0.9.53{% endblock %}
|
||||
{% block content %}
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
|
||||
@ -330,9 +330,10 @@ As of release {{ release }}.
|
||||
|
||||
<tr><td>i2p.streaming.maxWindowSize</td><td>128</td></tr>
|
||||
|
||||
<tr><td>i2p.streaming.profile</td><td>1 (bulk)</td><td>
|
||||
1=bulk; 2=interactive; see important notes <a href="#profile">below</a>.
|
||||
</td></tr>
|
||||
<tr><td>i2p.streaming.profile</td><td>1 (bulk)</td><td>{% trans -%}
|
||||
(2=interactive not supported)
|
||||
This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
|
||||
{%- endtrans %}</td></tr>
|
||||
|
||||
<tr><td>i2p.streaming.readTimeout</td><td>-1</td><td>{% trans -%}
|
||||
How long to block on read, in milliseconds. Negative means indefinitely.
|
||||
@ -533,29 +534,6 @@ Streaming may be configured to disable sending pongs with the configuration i2p.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
|
||||
<h3 id="profile">i2p.streaming.profile Notes</h3>
|
||||
<p>
|
||||
This option supports two values; 1=bulk and 2=interactive.
|
||||
The option provides a hint to the streaming library and/or router as to
|
||||
the traffic pattern that is expected.
|
||||
</p><p>
|
||||
"Bulk" means to optimize for high bandwidth, possibly at the expense of latency.
|
||||
This is the default.
|
||||
"Interactive" means to optimize for low latency, possibly at the expense of bandwidth or efficiency.
|
||||
Optimization strategies, if any, are implementation-dependent, and may include changes
|
||||
outside of the streaming protocol.
|
||||
</p><p>
|
||||
Through API version 0.9.63, Java I2P would return an error for any value other than 1 (bulk) and the tunnel would fail to start.
|
||||
As of API 0.9.64, Java I2P ignores the value.
|
||||
Through API version 0.9.63, i2pd ignored this option; it is implemented in i2pd as of API 0.9.64.
|
||||
</p><p>
|
||||
While the streaming protocol includes a flag field to pass the profile setting to the
|
||||
other end, this is not implemented in any known router.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h3 id="sharing">{% trans %}Control Block Sharing{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The streaming lib supports "TCP" Control Block sharing.
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Bittorrent over I2P{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-11{% endblock %}
|
||||
{% block accuratefor %}0.9.64{% endblock %}
|
||||
{% block lastupdated %}2023-01{% endblock %}
|
||||
{% block accuratefor %}0.9.57{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans -%}
|
||||
@ -58,19 +58,6 @@ For most low- to medium-bandwidth and low- to medium-connection counts, 3 is suf
|
||||
Please specify the tunnel quantity in the SESSION CREATE message
|
||||
to get consistent performance with the Java I2P and i2pd routers.
|
||||
</p><p>
|
||||
I2P supports multiple signature and encryption types.
|
||||
For compatibility, I2P defaults to old and inefficient types, so all clients should
|
||||
specify newer types.
|
||||
</p><p>
|
||||
If using SAM, the signature type is specified in the DEST GENERATE and SESSION CREATE (for transient) commands.
|
||||
All clients should set SIGNATURE_TYPE=7 (Ed25519).
|
||||
</p><p>
|
||||
The encryption type is specified in the SAM SESSION CREATE command or in i2cp options.
|
||||
Multiple encryption types are allowed.
|
||||
Some trackers support ECIES-X25519, some support ElGamal, and some support both.
|
||||
Clients should set i2cp.leaseSetEncType=4,0 (for ECIES-X25519 and ElGamal)
|
||||
so that they may connect to both.
|
||||
</p><p>
|
||||
DHT support requires SAM v3.3 PRIMARY and SUBSESSIONS for TCP and UDP over the same session.
|
||||
This will require substantial development effort on the client side, unless the client is written in Java.
|
||||
i2pd does not currently support SAM v3.3.
|
||||
@ -121,10 +108,7 @@ the tracker should probably decode and reject bad Base64 when announced.
|
||||
The default response type is non-compact. Clients may request a compact response with
|
||||
the parameter compact=1. A tracker may, but is not required to, return
|
||||
a compact response when requested.
|
||||
{%- endtrans %}
|
||||
Note: All popular trackers now support compact responses and at least one requires compact=1 in the announce.
|
||||
All clients should request and support compact responses.
|
||||
</p>
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Developers of new I2P clients
|
||||
|
@ -24,7 +24,7 @@
|
||||
<pre><code>git fetch $HOME/.i2p/i2psnark/i2p.i2p.bundle</code></pre>
|
||||
<h3 id="replace-the-bundle-remote-with-the-upstream-remote">{% trans -%}Replace the bundle remote with the upstream remote{%- endtrans %}</h3>
|
||||
<p>{% trans -%} Now that you have a bundle, you can keep up with changes by setting the remote to the upstream repository source. {%- endtrans %}</p>
|
||||
<pre><code>git remote set-url origin git@127.0.0.1:I2P_Developers/i2p.i2p</code></pre>
|
||||
<pre><code>git remote set-url origin git@127.0.0.1:i2p-hackers/i2p.i2p</code></pre>
|
||||
<h2 id="generating-a-bundle">{% trans -%}Generating a Bundle{%- endtrans %}</h2>
|
||||
<p>{% trans -%} First, follow the <a href="GIT.md">Git guide for Users</a> until you have a successfully <code>--unshallow</code>ed clone of clone of the i2p.i2p repository. If you already have a clone, make sure you run <code>git fetch --unshallow</code> before you generate a torrent bundle. {%- endtrans %}</p>
|
||||
<p>{% trans -%}Once you have that, simply run the corresponding ant target:{%- endtrans %}</p>
|
||||
|
@ -24,7 +24,7 @@ using the instructions on the home page.{%- endtrans %}</p>
|
||||
<img src="/_static/images/git/register.png" alt="" /><figcaption>Registration is easy!</figcaption>
|
||||
</figure>
|
||||
<h2 id="second-create-a-project-to-test-with">Second: Create a project to test with</h2>
|
||||
<p>{% trans -%} To make sure the setup process works, it helps to make a repository to test with from the server, and for the sake of this tutorial, we’re going to use a fork of the I2P router. First, browse to the I2P_Developers/i2p.i2p repository: {%- endtrans %}</p>
|
||||
<p>{% trans -%} To make sure the setup process works, it helps to make a repository to test with from the server, and for the sake of this tutorial, we’re going to use a fork of the I2P router. First, browse to the i2p-hackers/i2p.i2p repository: {%- endtrans %}</p>
|
||||
<figure>
|
||||
<img src="/_static/images/git/explore.png" alt="" /><figcaption>Browse to i2p.i2p</figcaption>
|
||||
</figure>
|
||||
@ -99,7 +99,7 @@ git fetch origin</code></pre>
|
||||
</ul>
|
||||
<ol type="1">
|
||||
<li><p>{% trans -%}Set up a second remote in your local repository using the upstream source code.{%- endtrans %}</p>
|
||||
<pre><code>git remote add upstream git@127.0.0.1:I2P_Developers/i2p.i2p</code></pre></li>
|
||||
<pre><code>git remote add upstream git@127.0.0.1:i2p-hackers/i2p.i2p</code></pre></li>
|
||||
<li><p>{% trans -%}Pull in any upstream changes on your current master:{%- endtrans %}</p>
|
||||
<pre><code>git pull upstream master</code></pre></li>
|
||||
<li><p>{% trans -%}Before making any changes to the source code, check out a new feature branch to develop on:{%- endtrans %}</p>
|
||||
@ -110,7 +110,7 @@ git push origin feature-branch-name</code></pre></li>
|
||||
<li><p>{% trans -%}Submit a merge request. When the merge request is approved and brought into the upstream master, check out the master locally and pull in the changes:{%- endtrans %}</p>
|
||||
<pre><code>git checkout master
|
||||
git pull upstream master</code></pre></li>
|
||||
<li><p>{% trans -%}Whenever a change to the upstream master(I2P_Developers/i2p.i2p) is made, you can update your master code using this procedure as well.{%- endtrans %}</p>
|
||||
<li><p>{% trans -%}Whenever a change to the upstream master(i2p-hackers/i2p.i2p) is made, you can update your master code using this procedure as well.{%- endtrans %}</p>
|
||||
<pre><code>git checkout master
|
||||
git pull upstream master</code></pre></li>
|
||||
</ol>
|
||||
|
@ -79,12 +79,12 @@ alt="{{ _('Configure port') }}" title="{{ _('Pidgin Step Four') }}">
|
||||
alt="{{ _('Add a server') }}" title="{{ _('XChat Step One') }}">
|
||||
|
||||
<p>{% trans %}Create a new network named "Irc2P" to configure for I2P IRC. Click
|
||||
the "Edit" button on the right-hand side. Make sure you disable TLS and SSL inside I2P.{% endtrans %}</p>
|
||||
the "Edit" button on the right-hand side.{% endtrans %}</p>
|
||||
|
||||
<img src="{{ url_for('static', filename='images/irc/xchat-irc-1.png') }}"
|
||||
alt="{{ _('Add a server') }}" title="{{ _('XChat Step Two') }}">
|
||||
|
||||
<p>{% trans %}Change the value in "Servers" from the default to `localhost/6668`,
|
||||
<p>{% trans %}Change the value in "Servers" from the default to `localhost/6669`,
|
||||
and configure the default channels you want to join. I suggest #i2p and #i2p-dev
|
||||
{% endtrans %}</p>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}The Network Database{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2025-03{% endblock %}
|
||||
{% block accuratefor %}0.9.65{% endblock %}
|
||||
{% block lastupdated %}2023-11{% endblock %}
|
||||
{% block accuratefor %}0.9.59{% endblock %}
|
||||
{% block content %}
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
|
||||
@ -56,16 +56,14 @@ to be present:
|
||||
<li><b>M</b>: {% trans amount='48 - 64 KBps' %}{{ amount }} shared bandwidth{% endtrans %}</li>
|
||||
<li><b>N</b>: {% trans amount='64 - 128 KBps' %}{{ amount }} shared bandwidth{% endtrans %}</li>
|
||||
<li><b>O</b>: {% trans amount='128 - 256 KBps' %}{{ amount }} shared bandwidth{% endtrans %}</li>
|
||||
<li><b>P</b>: {% trans amount='256 - 2000 KBps' %}{{ amount }} shared bandwidth{% endtrans %} (as of release 0.9.20, see note below)</li>
|
||||
<li><b>P</b>: {% trans amount='256 - 2000 KBps' %}{{ amount }} shared bandwidth{% endtrans %} (as of release 0.9.20)</li>
|
||||
<li><b>R</b>: {% trans %}Reachable{% endtrans %}</li>
|
||||
<li><b>U</b>: {% trans %}Unreachable{% endtrans %}</li>
|
||||
<li><b>X</b>: {% trans amount='2000 KBps' %}Over {{ amount }} shared bandwidth{% endtrans %} (as of release 0.9.20, see note below)</li>
|
||||
<li><b>X</b>: {% trans amount='2000 KBps' %}Over {{ amount }} shared bandwidth{% endtrans %} (as of release 0.9.20)</li>
|
||||
</ul>
|
||||
"Shared bandwidth" == (share %) * min(in bw, out bw)
|
||||
<br>
|
||||
For compatibility with older routers, a router may publish multiple bandwidth letters, for example "PO".
|
||||
<br>
|
||||
Note: the boundary between the P and X bandwidth classes may be either 2000 or 2048 KBps, implementor's choice.
|
||||
</li>
|
||||
<li><b>netId</b> = 2
|
||||
({% trans %}Basic network compatibility - A router will refuse to communicate with a peer having a different netId{% endtrans %})
|
||||
@ -531,34 +529,7 @@ Routing keys are never sent on-the-wire in any I2NP message, they are only used
|
||||
determination of distance.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="segmentation">{% trans %}Network Database Segmentation - Sub-Databases{% endtrans %}</h2>
|
||||
<p>{% trans -%}Traditionally Kademlia-style DHT's are not concerned with preserving the unlinkability of information stored on any particular node in the DHT.
|
||||
For example, a piece of information may be stored to one node in the DHT, then requested back from that node unconditionally.
|
||||
Within I2P and using the netDb, this is not the case, information stored in the DHT may only be shared under certain known circumstances where it is "safe" to do so.
|
||||
This is to prevent a class of attacks where a malicious actor can try to associate a client tunnel with a router by sending a store to a client tunnel, then requesting it back directly from the suspected "Host" of the client tunnel.
|
||||
{%- endtrans %}</p>
|
||||
<h3>{% trans %}Segmentation Structure{% endtrans %}</h3>
|
||||
<p>{% trans -%}I2P routers can implement effective defenses against the attack class provided a few conditions are met.
|
||||
A network database implementation should be able to keep track of whether a database entry was recieved down a client tunnel or directly.
|
||||
If it was recieved down a client tunnel, then it should also keep track of which client tunnel it was recieved through, using the client's local destination.
|
||||
If the entry was recieved down multiple client tunnels, then the netDb should keep track of all destinations where the entry was observed.
|
||||
It should also keep track of whether an entry was recieved as a reply to a lookup, or as a store.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}In both the Java and C++ implementations, this achieved by using a single "Main" netDb for direct lookups and floodfill operations first.
|
||||
This main netDb exists in the router context.
|
||||
Then, each client is given it's own version of the netDb, which is used to capture database entries sent to client tunnels and respond to lookups sent down client tunnels.
|
||||
We call these "Client Network Databases" or "Sub-Databases" and they exist in the client context.
|
||||
The netDb operated by the client exists for the lifetime of the client only and contains only entries that are communicated with the client's tunnels.
|
||||
This makes it impossible for entries sent down client tunnels to overlap with entries sent directly to the router.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}Additionally, each netDb needs to be able to remember if a database entry was recieved because it was sent to one of our destinations, or because it was requested by us as part of a lookup.
|
||||
If a database entry it was recieved as a store, as in some other router sent it to us, then a netDb should respond to requests for the entry when another router looks up the key.
|
||||
However, if it was recieved as a reply to a query, then the netDb should only reply to a query for the entry if the entry had already been stored to the same destination.
|
||||
A client should never answer queries with an entry from the main netDb, only it's own client network database.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}These strategies should be taken and used combined so that both are applied.
|
||||
In combination, they "Segment" the netDb and secure it against attacks.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2 id="delivery">{% trans %}Storage, Verification, and Lookup Mechanics{% endtrans %}</h2>
|
||||
|
||||
@ -613,13 +584,7 @@ The floodfill router replies with a
|
||||
with the Message ID set to the value of the Reply Token.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>In some circumstances, a router may also send the RouterInfo DatabaseStoreMessage out
|
||||
an exploratory tunnel; for example, due to connection limits, connection incompatibility,
|
||||
or a desire to hide the actual IP from the floodfill.
|
||||
The floodfill may not accept such a store in times of overload or based
|
||||
on other criteria; whether to explicitly declare non-direct store of a RouterInfo illegal is a topic
|
||||
for further study.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h3>{% trans %}LeaseSet Storage to Floodfills{% endtrans %}</h3>
|
||||
@ -642,13 +607,6 @@ This message is sent back to one of the client's inbound tunnels.
|
||||
|
||||
|
||||
<h3>{% trans %}Flooding{% endtrans %}</h3>
|
||||
<p>
|
||||
Like any router, a floodfill uses various criteria to validate the LeaseSet or RouterInfo before storing it locally.
|
||||
These criteria may be adaptive and dependent on current conditions including current load, netdb size,
|
||||
and other factors.
|
||||
All validation must be done before flooding.
|
||||
</p>
|
||||
|
||||
<p>{% trans floodsize=3 -%}
|
||||
After a floodfill router receives a DatabaseStoreMessage containing a
|
||||
valid RouterInfo or LeaseSet which is newer than that previously stored in its
|
||||
@ -669,14 +627,6 @@ as this is a direct connection, so there are no intervening routers
|
||||
The other routers do not reply or re-flood, as the Reply Token is zero.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>
|
||||
Floodfills must not flood via tunnels; the DatabaseStoreMessage must be sent over a direct connection.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Floodfills must never flood an expired LeaseSet or a RouterInfo published more than one hour ago.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 id="lookup">{% trans %}RouterInfo and LeaseSet Lookup{% endtrans %}</h3>
|
||||
<p>{% trans i2np=site_url('docs/protocol/i2np') -%}
|
||||
|
@ -1,16 +1,8 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Peer Profiling and Selection{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-02{% endblock %}
|
||||
{% block accuratefor %}0.9.62{% endblock %}
|
||||
{% block lastupdated %}{% trans %}July 2010{% endtrans %}{% endblock %}
|
||||
{% block accuratefor %}0.8{% endblock %}
|
||||
{% block content %}
|
||||
<h2>NOTE</h2>
|
||||
This page describes the Java I2P implementation of peer profiling and selection as of 2010.
|
||||
While still broadly accurate, some details may no longer be correct.
|
||||
We continue to evolve banning, blocking, and selection strategies to address newer threats, attacks, and network conditions.
|
||||
The current network has multiple router implementations with various versions.
|
||||
Other I2P implementations may have completely different profiling and selection strategies,
|
||||
or may not use profiling at all.
|
||||
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
|
||||
<h3>{% trans %}Peer Profiling{% endtrans %}</h3>
|
||||
|
@ -1,7 +1,5 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}I2P: A scalable framework for anonymous communication{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2025-01{% endblock %}
|
||||
{% block accuratefor %}0.9.65{% endblock %}
|
||||
{% block content_nav %}
|
||||
<ul>
|
||||
<li><a href="#intro">{% trans %}Introduction{% endtrans %}</a></li>
|
||||
@ -15,40 +13,10 @@
|
||||
<li><a href="#op.crypto">{% trans %}Cryptography{% endtrans %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#future">{% trans %}Future{% endtrans %}</a>
|
||||
<ul>
|
||||
<li><a href="#future.restricted">{% trans %}Restricted Routes{% endtrans %}</a></li>
|
||||
<li><a href="#future.variablelatency">{% trans %}Variable Latency{% endtrans %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#similar">{% trans %}Similar Networks{% endtrans %}</a>
|
||||
<ul>
|
||||
<li><a href="#similar.tor">{% trans %}Tor{% endtrans %}</a></li>
|
||||
<li><a href="#similar.freenet">{% trans %}Freenet{% endtrans %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#app">{% trans %}Application Layer{% endtrans %}</a>
|
||||
<ul>
|
||||
<li><a href="#app.streaming">{% trans %}Streaming{% endtrans %}</a></li>
|
||||
<li><a href="#app.naming">{% trans %}Naming and Addressbook{% endtrans %}</a></li>
|
||||
<li><a href="#app.i2psnark">{% trans %}I2PSnark{% endtrans %}</a></li>
|
||||
<li><a href="#app.i2ptunnel">{% trans %}I2PTunnel{% endtrans %}</a></li>
|
||||
<li><a href="#app.i2pmail">{% trans %}I2P Email{% endtrans %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>
|
||||
NOTE: This document was originally written by jrandom in 2003.
|
||||
While we strive to keep it current, some information may be obsolete or incomplete.
|
||||
The transport and cryptography sections are current as of 2025-01.
|
||||
</p>
|
||||
|
||||
<h1 id="intro">{% trans %}Introduction{% endtrans %}</h1>
|
||||
<p>{% trans -%}
|
||||
I2P is a scalable, self organizing, resilient packet switched anonymous
|
||||
@ -62,16 +30,20 @@ anonymity set of users already running on top of I2P.
|
||||
<p>{% trans -%}
|
||||
Applications available already provide the full range of typical Internet activities -
|
||||
<b>anonymous</b> web browsing, web hosting, chat, file sharing, e-mail,
|
||||
blogging and content syndication, as well as several other applications under development.
|
||||
blogging and content syndication, newsgroups, as well as several other applications under development.
|
||||
{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans %}Web browsing: using any existing browser that supports using a proxy.{% endtrans %}</li>
|
||||
<li>{% trans %}Chat: IRC and other protocols{% endtrans %}</li>
|
||||
<li>{% trans %}Chat: IRC, Jabber, <a href="#app.i2pmessenger">I2P-Messenger</a>.{% endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
File sharing: <a href="#app.i2psnark">I2PSnark</a> and other applications
|
||||
File sharing: <a href="#app.i2psnark">I2PSnark</a>, <a href="#app.robert">Robert</a>, <a href="#app.imule">iMule</a>,
|
||||
<a href="#app.i2phex">I2Phex</a>, <a href="#app.pybit">PyBit</a>, <a href="#app.i2pbt">I2P-bt</a>
|
||||
and others.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans %}E-mail: <a href="#app.i2pmail">susimail</a> and other applications{% endtrans %}</li>
|
||||
<li>{% trans %}Blog: using any local web server, or available plugins{% endtrans %}</li>
|
||||
<li>{% trans %}E-mail: <a href="#app.i2pmail">susimail</a> and <a href="#app.i2pbote">I2P-Bote</a>.{% endtrans %}</li>
|
||||
<li>{% trans %}Blog: using e.g. the pebble plugin or the distributed blogging software <a href="#app.syndie">Syndie</a>.{% endtrans %}</li>
|
||||
<li>{% trans %}Distributed Data Store: Save your data redundantly in the Tahoe-LAFS cloud over I2P.{% endtrans %}</li>
|
||||
<li>{% trans %}Newsgroups: using any newsgroup reader that supports using a proxy.{% endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
@ -143,7 +115,6 @@ and an end point. Messages can be sent only in one way. To send messages back,
|
||||
another tunnel is required.
|
||||
{%- endtrans %}</p>
|
||||
<div class="box" style="text-align:center;">
|
||||
<br /><br />
|
||||
<img src="{{ url_for('static', filename='images/tunnels.png') }}" alt="{{ _('Inbound and outbound tunnel schematic') }}" title="{{ _('Inbound and outbound tunnel schematic') }}" />
|
||||
<br /><br />
|
||||
{% trans %}Figure 1: Two types of tunnels exist: inbound and outbound.{% endtrans %}
|
||||
@ -197,10 +168,8 @@ She can then send a build message to the first hop, requesting the construction
|
||||
that router to send the construction message onward, until the tunnel has been constructed.
|
||||
{%- endtrans %}</p>
|
||||
<div class="box" style="text-align:center;">
|
||||
<br /><br />
|
||||
<img src="{{ url_for('static', filename='images/netdb_get_routerinfo_1.png') }}" alt="{{ _('Request information on other routers') }}" title="{{ _('Request information on other routers') }}" />
|
||||
|
||||
<br /><br />
|
||||
<img src="{{ url_for('static', filename='images/netdb_get_routerinfo_2.png') }}" alt="{{ _('Build tunnel using router information') }}" title="{{ _('Build tunnel using router information') }}" />
|
||||
<br /><br />
|
||||
{% trans %}Figure 2: Router information is used to build tunnels.{% endtrans %}
|
||||
@ -223,7 +192,6 @@ recent LeaseSet with the message so that Bob doesn't need to do a netDb lookup
|
||||
for it when he wants to reply, but this is optional.
|
||||
{%- endtrans %}</p>
|
||||
<div class="box" style="text-align:center;">
|
||||
<br /><br />
|
||||
<img src="{{ url_for('static', filename='images/netdb_get_leaseset.png') }}" alt="{{ _('Connect tunnels using LeaseSets') }}" title="{{ _('Connect tunnels using leaseSets') }}" />
|
||||
<br /><br />
|
||||
{% trans %}Figure 3: LeaseSets are used to connect outbound and inbound tunnels.{% endtrans %}
|
||||
@ -362,12 +330,10 @@ but a basic explanation is available below.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
All I2P routers contain a local netDb, but not all routers participate in the DHT
|
||||
or respond to leaseset lookups.
|
||||
Those routers that do participate in the DHT and respond to leaseset lookups
|
||||
are called 'floodfills'.
|
||||
Routers may be manually configured as floodfills, or automatically become floodfill
|
||||
if they have enough capacity and meet other criteria for reliable operation.
|
||||
A percentage of I2P users are appointed as 'floodfill peers'.
|
||||
Currently, I2P installations that have a lot of bandwidth and are fast enough,
|
||||
will appoint themselves as floodfill as soon as the number of existing floodfill routers
|
||||
drops too low.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans netdb=site_url('docs/how/network-database') -%}
|
||||
@ -404,7 +370,7 @@ Some additional remarks are also important.
|
||||
<p>{% trans -%}
|
||||
One could only want specific people to be able to reach a destination.
|
||||
This is possible by not publishing the destination in the netDb. You will however have to transmit the destination by other means.
|
||||
This is supported by 'encrypted leaseSets'. These leaseSets can only be decoded by people with access to the decryption key.
|
||||
An alternative are the 'encrypted leaseSets'. These leaseSets can only be decoded by people with access to the decryption key.
|
||||
{%- endtrans %}</p>
|
||||
</li>
|
||||
<li>
|
||||
@ -414,16 +380,16 @@ Bootstrapping the netDb is quite simple. Once a router manages to receive a sing
|
||||
it can query that router for references to other routers in the network.
|
||||
Currently, a number of users post their routerInfo files to a website to make this information available.
|
||||
I2P automatically connects to one of these websites to gather routerInfo files and bootstrap.
|
||||
I2P calls this bootstrap process "reseeding".
|
||||
{%- endtrans %}</p>
|
||||
</li>
|
||||
<li>
|
||||
<b>{% trans %}Lookup scalability:{% endtrans %}</b>
|
||||
<p>{% trans -%}
|
||||
Lookups in the I2P network are iterative, not recursive.
|
||||
If a lookup from a floodfill fails, the lookup will be repeated to the next-closest floodfill.
|
||||
The floodfill does not recursively ask another floodfill for the data.
|
||||
Iterative lookups are scalable to large DHT networks.
|
||||
Lookups in the I2P network are not forwarded to other netDb routers.
|
||||
Currently, this is not a major problem, since the network is not very large.
|
||||
However, as the network grows, not all routerInfo and leaseSet files will be present
|
||||
on each netDb router. This will cause a deterioration of the percentage of successful lookups.
|
||||
Because of this, refinements to the netDb will be done in the next releases.
|
||||
{%- endtrans %}</p>
|
||||
</li>
|
||||
</ul>
|
||||
@ -437,29 +403,15 @@ communicate with other routers aren't critical - three separate protocols
|
||||
have been used at different points to provide those bare necessities.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans ntcp=site_url('docs/transport/ntcp'), ssu=site_url('docs/transport/ssu'), ntcp2=spec_url('ntcp2'), ssu2=spec_url('ssu2') -%}
|
||||
I2P currently supports two transport protocols,
|
||||
<a href="{{ ntcp2 }}">NTCP2</a> over TCP, and <a href="{{ ssu2 }}">SSU2</a> over UDP.
|
||||
These have replaced the previous versions of the protocols,
|
||||
<a href="{{ ntcp }}">NTCP</a> and <a href="{{ ssu }}">SSU</a>, which are now deprecated.
|
||||
Both protocols support both IPv4 and IPv6.
|
||||
By supporting both TCP and UDP transports, I2P can effectively traverse most firewalls,
|
||||
including those intended to block traffic in restrictive censorship regimes.
|
||||
NTCP2 and SSU2 were designed to use modern encryption standards,
|
||||
improve traffic identification resistance,
|
||||
increase efficiency and security,
|
||||
and make NAT traversal more robust.
|
||||
Routers publish each supported transport and IP address in the network database.
|
||||
Routers with access to public IPv4 and IPv6 networks will usually publish
|
||||
four addresses, one for each combination of NTCP2/SSU2 with IPv4/IPv6.
|
||||
<p>{% trans ssu=site_url('docs/transport/ssu') -%}
|
||||
I2P started with a TCP-based protocol which
|
||||
has since been disabled. Then, to accommodate the need for high degree communication
|
||||
(as a number of routers will end up speaking with many others), I2P moved
|
||||
from a TCP based transport to a <a href="{{ ssu }}">UDP-based one</a> - "Secure
|
||||
Semireliable UDP", or "SSU".
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans ssu=site_url('docs/transport/ssu'), ssu2=spec_url('ssu2') -%}
|
||||
<a href="{{ ssu2 }}">SSU2</a> supports and extends the goals of SSU.
|
||||
SSU2 has many similarities to other modern UDP-based protocols such as Wireguard and QUIC.
|
||||
In addition to the reliable transport of network messages over UDP,
|
||||
SSU2 provides specialized facilities for peer-to-peer, cooperative
|
||||
IP address detection, firewall detection, and NAT traversal.
|
||||
<p>{% trans ssu=site_url('docs/transport/ssu') -%}
|
||||
As described in the <a href="{{ ssu }}">SSU spec</a>:
|
||||
{%- endtrans %}</p>
|
||||
|
||||
@ -473,11 +425,14 @@ sufficient for home users. In addition, it should support techniques for address
|
||||
network obstacles, like most NATs or firewalls.
|
||||
{%- endtrans %}</blockquote>
|
||||
|
||||
<p>{% trans ntcp2=spec_url('ntcp2') -%}
|
||||
NTCP2 supports and extends the goals of NTCP.
|
||||
It provides an efficient and fully encrypted transport of network messages over TCP,
|
||||
and resistance to traffic identification,
|
||||
using modern encryption standards.
|
||||
<p>{% trans ntcp=site_url('docs/transport/ntcp') -%}
|
||||
Following the introduction of SSU, after issues with congestion collapse
|
||||
appeared, a new NIO-based TCP transport called <a href="{{ ntcp }}">NTCP</a>
|
||||
was implemented. It is enabled by default for outbound connections only. Those
|
||||
who configure their NAT/firewall to allow inbound connections and specify
|
||||
the external host and port (dyndns/etc is ok) on /config.jsp can receive inbound
|
||||
connections. As NTCP is NIO based, so it doesn't suffer from the 1 thread
|
||||
per connection issues of the old TCP transport.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
@ -488,51 +443,28 @@ Transports may reply with different bids, depending on whether there is already
|
||||
an established connection to the peer.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The bid (priority) values are implementation-dependent and
|
||||
may vary based on traffic conditions, connection counts, and other factors.
|
||||
Routers also publish their transport preferences for inbound connections in the network database
|
||||
as transport "costs" for each transport and address.
|
||||
<p>{% trans ntcp=site_url('docs/transport/ntcp') -%}
|
||||
The current implementation ranks NTCP as the highest-priority transport
|
||||
for outbound connections in most situations. SSU is enabled for both outbound
|
||||
and inbound connections. Your firewall and your I2P router must be configured
|
||||
to allow inbound NTCP connections. For further information see the <a href="{{ ntcp }}">NTCP
|
||||
page</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="op.crypto">{% trans %}Cryptography{% endtrans %}</h2>
|
||||
|
||||
<p>{% trans -%}
|
||||
I2P uses cryptography at several protocol layers for encryption, authentication, and verification.
|
||||
The major protocol layers are: transports, tunnel build messages, tunnel layer encryption,
|
||||
network database messages, and end-to-end (garlic) messages.
|
||||
I2P's original design used a small set of cryptographic primitives that at the time were considered secure.
|
||||
These included ElGamal asymmetric encryption, DSA-SHA1 signatures,
|
||||
AES256/CBC symmetric encryption, and SHA-256 hashes.
|
||||
As available computing power increased and cryptographic research evolved substantially
|
||||
over the years, I2P needed to upgrade its primitives and protocols.
|
||||
Therefore, we added a concept of "encryption types" and "signature types",
|
||||
and extended our protocols to include these identifiers and indicate support.
|
||||
This allows us to periodically update and extend the network support for
|
||||
modern cryptography and future-proof the network for new primitives,
|
||||
without breaking backward compatibility or requiring a "flag day" for network updates.
|
||||
Some signature and encryption types are also reserved for experimental use.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The current primitives used in most protocol layers are X25519 key exchange, EdDSA signatures,
|
||||
ChaCha20/Poly1305 authenticated symmetric encryption, and SHA-256 hashes.
|
||||
AES256 is still used for tunnel layer encryption.
|
||||
These modern protocols are used for the vast majority of network communication
|
||||
Older primitives including ElGamal, ECDSA, and DSA-SHA1 continue to be supported by most implementations
|
||||
for backward compatibility when communicating with older routers.
|
||||
Some old protocols have been deprecated and/or removed completely.
|
||||
In the near future we will begin research on a migration to post-quantum (PQ)
|
||||
or hybrid-PQ encryption and signatures to maintain our robust security standards.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
These cryptographic primitives are combined together to
|
||||
A bare minimum set of cryptographic primitives are combined together to
|
||||
provide I2P's layered defenses against a variety of adversaries. At the lowest
|
||||
level, inter-router communication is protected by the transport layer security.
|
||||
<a href="#op.tunnels">Tunnel</a> messages passed over the transports
|
||||
have their own layered encryption.
|
||||
Various other messages are passed along inside "garlic messages", which are also encrypted.
|
||||
level, inter router communication is protected by the transport layer security
|
||||
- SSU encrypts each packet with AES256/CBC with both an explicit IV and MAC
|
||||
(HMAC-MD5-128) after agreeing upon an ephemeral session key through a 2048bit
|
||||
Diffie-Hellman exchange, station-to-station authentication with the other
|
||||
router's DSA key, plus each network message has their own hash for local integrity
|
||||
checking. <a href="#op.tunnels">Tunnel</a> messages passed over the transports
|
||||
have their own layered AES256/CBC encryption with an explicit IV and verified
|
||||
at the tunnel endpoint with an additional SHA256 hash. Various other messages
|
||||
are passed along inside "garlic messages", which are encrypted with ElGamal/AES+SessionTags
|
||||
(explained below).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3 id="op.garlic">{% trans %}Garlic messages{% endtrans %}</h3>
|
||||
@ -544,10 +476,10 @@ into a garlic message whenever the message would otherwise be passing in clearte
|
||||
through a peer who should not have access to the information - for instance,
|
||||
when a router wants to ask another router to participate in a tunnel, they
|
||||
wrap the request inside a garlic, encrypt that garlic to the receiving router's
|
||||
public key, and forward it through a tunnel. Another example
|
||||
2048bit ElGamal public key, and forward it through a tunnel. Another example
|
||||
is when a client wants to send a message to a destination - the sender's router
|
||||
will wrap up that data message (alongside some other messages) into a garlic,
|
||||
encrypt that garlic to the public key published in the recipient's
|
||||
encrypt that garlic to the 2048bit ElGamal public key published in the recipient's
|
||||
leaseSet, and forward it through the appropriate tunnels.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
@ -568,17 +500,11 @@ not currently used in the existing implementation.
|
||||
<p>{% trans -%}
|
||||
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. The original combination was referred
|
||||
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 simple use of 2048bit ElGamal, AES256, SHA256 and 32 byte nonces.
|
||||
While this protocol is still supported, most of the network has migrated to
|
||||
a new protocol, ECIES-X25519-AEAD-Ratchet.
|
||||
This protocol combines X25519, ChaCha20/Poly1305, and a synchronized PRNG
|
||||
to generate the 32 byte nonces.
|
||||
Both protocols will be briefly described below.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4 id="op.elg">ElGamal/AES+SessionTags</h4>
|
||||
<p>{% trans -%}
|
||||
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
|
||||
@ -620,50 +546,24 @@ drop the ones previously assumed to be properly delivered, reverting back
|
||||
to the full expensive ElGamal encryption.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h4 id="op.ratchet">ECIES-X25519-AEAD-Ratchet</h4>
|
||||
<p>{% trans -%}
|
||||
ElGamal/AES+SessionTags required substantial overhead in a number of ways.
|
||||
CPU usage was high because ElGamal is quite slow.
|
||||
Bandwidth was excessive because large numbers of session tags had to be delivered in advance,
|
||||
and because ElGamal public keys are very large.
|
||||
Memory usage was high due to the requirement to store large amounts of session tags.
|
||||
Reliability was hampered by lost session tag delivery.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
ECIES-X25519-AEAD-Ratchet was designed to address these issues.
|
||||
X25519 is used for key exchange.
|
||||
ChaCha20/Poly1305 is used for authenticated symmetric encryption.
|
||||
Encryption keys are "double ratcheted" or rotated periodically.
|
||||
Session tags are reduced from 32 bytes to 8 bytes and are generated with a PRNG.
|
||||
The protocol has many similarities to the signal protocol used in Signal and WhatsApp.
|
||||
This protocol provides substantially lower overhead in CPU, RAM, and bandwidth.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The session tags are generated from a deterministic synchronized PRNG running
|
||||
at both ends of the session to generate session tags and session keys.
|
||||
The PRNG is a HKDF using a SHA-256 HMAC, and is seeded from the X25519 DH result.
|
||||
Session tags are never transmitted in advance; they are only included with the message.
|
||||
The receiver stores a limited number of session keys, indexed by session tag.
|
||||
The sender does not need to store any session tags or keys because they
|
||||
are not sent in advance; they may be generated on-demand.
|
||||
By keeping
|
||||
One alternative is to transmit only a single session tag, and from that,
|
||||
seed a deterministic PRNG for determining what tags to use or expect. By keeping
|
||||
this PRNG roughly synchronized between the sender and recipient (the recipient
|
||||
precomputes a window of the next e.g. 50 tags), the overhead of periodically
|
||||
bundling a large number of tags is removed.
|
||||
bundling a large number of tags is removed, allowing more options in the space/time
|
||||
tradeoff, and perhaps reducing the number of ElGamal encryptions necessary.
|
||||
However, it would depend upon the strength of the PRNG to provide the necessary
|
||||
cover against internal adversaries, though perhaps by limiting the amount
|
||||
of times each PRNG is used, any weaknesses can be minimized. At the moment,
|
||||
there are no immediate plans to move towards these synchronized PRNGs.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h1 id="future">{% trans %}Future{% endtrans %}</h1>
|
||||
<p>{% trans -%}
|
||||
I2P's protocols are efficient on most platforms, including cell phones,
|
||||
and secure for most threat models. However, there
|
||||
While I2P is currently functional and sufficient for many scenarios, there
|
||||
are several areas which require further improvement to meet the needs of those
|
||||
facing powerful state-sponsored adversaries, and to meet the threats of
|
||||
continued cryptographic advances and ever-increasing computing power.
|
||||
Two possible features, restricted routes and variable latency,
|
||||
were propsed by jrandom in 2003. While we no longer plan to
|
||||
implement these features, they are described below.
|
||||
facing more powerful adversaries as well as substantial user experience optimization.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="future.restricted">{% trans %}Restricted route operation{% endtrans %}</h2>
|
||||
@ -684,7 +584,7 @@ Restricted route operation, where there are limits to what peers are reachable
|
||||
directly, has several different functional and anonymity implications, dependent
|
||||
upon how the restricted routes are handled. At the most basic level, restricted
|
||||
routes exist when a peer is behind a NAT or firewall which does not allow
|
||||
inbound connections. This was largely addressed by integrating
|
||||
inbound connections. This was largely addressed in I2P 0.6.0.6 by integrating
|
||||
distributed hole punching into the transport layer, allowing people behind
|
||||
most NATs and firewalls to receive unsolicited connections without any configuration.
|
||||
However, this does not limit the exposure of the peer's IP address to routers
|
||||
@ -710,7 +610,8 @@ tunnel gateway. The concept of 'client routers' simply extends the restricted
|
||||
route by not publishing any router addresses. Such a router would not even
|
||||
need to publish their routerInfo in the netDb, merely providing their self
|
||||
signed routerInfo to the peers that it contacts (necessary to pass the router's
|
||||
public keys).
|
||||
public keys). Both levels of restricted route operation are planned for I2P
|
||||
2.0.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
@ -725,20 +626,6 @@ of using a hostile peer to get connected is small enough, or trusted (and
|
||||
perhaps temporary) peers are used instead.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Restricted routes are complex, and the overall goal has been largely abandoned.
|
||||
Several related improvements have greatly reduced the need for them.
|
||||
We now support UPnP to automatically open firewall ports.
|
||||
We support both IPv4 and IPv6.
|
||||
SSU2 improved address detection, firewall state determination, and cooperative NAT hole punching.
|
||||
SSU2, NTCP2, and address compatibility checks ensure that tunnel hops can connect
|
||||
before the tunnel is built.
|
||||
GeoIP and country identification allow us to avoid peers in countries with restrictive firewalls.
|
||||
Support for "hidden" routers behind those firewalls has improved.
|
||||
Some implementations also support connections to peers on overlay networks such as Yggdrasil.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2 id="future.variablelatency">{% trans %}Variable latency{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
Even though the bulk of I2P's initial efforts have been on low latency communication,
|
||||
@ -758,14 +645,20 @@ or, most likely, to a remote client destination.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
The goal of variable latency services requires substantial resources
|
||||
for store-and-forward mechanisms to support it.
|
||||
These mechanisms can and are supported in various messaging applications,
|
||||
such as i2p-bote.
|
||||
At the network level, alternative networks such as Freenet provide these services.
|
||||
We have decided not to pursue this goal at the I2P router level.
|
||||
There are a substantial number of ways to exploit this capacity for high
|
||||
latency comm in I2P, but for the moment, doing so has been scheduled for the
|
||||
I2P 3.0 release. In the meantime, those requiring the anonymity that high
|
||||
latency comm can offer should look towards the application layer to provide
|
||||
it.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="future.open">{% trans %}Open questions{% endtrans %}</h2>
|
||||
<ul>
|
||||
<li>{% trans %}How to get rid of the timing constraint?{% endtrans %}</li>
|
||||
<li>{% trans %}Can we deal with the sessionTags more efficiently?{% endtrans %}</li>
|
||||
<li>{% trans %}What, if any, batching/mixing strategies should be made available on the tunnels?{% endtrans %}</li>
|
||||
<li>{% trans %}What other tunnel peer selection and ordering strategies should be available?{% endtrans %}</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="similar">{% trans %}Similar systems{% endtrans %}</h1>
|
||||
|
||||
@ -781,8 +674,6 @@ two in particular are pulled out here - Tor and Freenet.
|
||||
|
||||
<p>{% trans comparisons=site_url('comparison') -%}
|
||||
See also the <a href="{{ comparisons }}">Network Comparisons Page</a>.
|
||||
Note that these descriptions were written by jrandom in 2003 and
|
||||
may not currently be accurate.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="similar.tor">Tor</h2>
|
||||
@ -833,6 +724,11 @@ in a tunnel is important, as an adversary would otherwise be able to mount
|
||||
a series of powerful predecessor, intersection, and traffic confirmation attacks.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Tor's support for a second tier of "onion proxies" does offer a non-trivial
|
||||
degree of anonymity while requiring a low cost of entry, while I2P will not
|
||||
offer this topology until <a href="#future.restricted">2.0</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
On the whole, Tor and I2P complement each other in their focus - Tor works
|
||||
@ -878,6 +774,20 @@ Freenet team will pursue efforts in that direction, if not simply reusing
|
||||
(or helping to improve, as necessary) existing mixnets like I2P or Tor.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
It is worth mentioning that there has recently been discussion and work
|
||||
by the Freenet developers on a "globally scalable darknet" using restricted
|
||||
routes between peers of various trust. While insufficient information has
|
||||
been made publicly available regarding how such a system would operate for
|
||||
a full review, from what has been said the anonymity and scalability claims
|
||||
seem highly dubious. In particular, the appropriateness for use in hostile
|
||||
regimes against state level adversaries has been tremendously overstated,
|
||||
and any analysis on the implications of resource scarcity upon the scalability
|
||||
of the network has seemingly been avoided. Further questions regarding susceptibility
|
||||
to traffic analysis, trust and other topics do exist, but a more in-depth
|
||||
review of this "globally scalable darknet" will have to wait until the Freenet
|
||||
team makes more information available.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h1 id="app">Appendix A: Application layer</h1>
|
||||
<p>{% trans -%}
|
||||
@ -981,6 +891,24 @@ systems can plug into, allowing end users to drive what sort of naming tradeoffs
|
||||
they prefer.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.syndie">Syndie</h2>
|
||||
<p><i>{% trans -%}
|
||||
The old Syndie bundled with I2P has been replaced by the new Syndie which
|
||||
is distributed separately. For more information see the <a href="http://syndie.i2p2.de/">Syndie</a>
|
||||
pages.
|
||||
{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans -%}
|
||||
Syndie is a safe, anonymous blogging / content publication / content aggregation
|
||||
system. It lets you create information, share it with others, and read posts
|
||||
from those you're interested in, all while taking into consideration your
|
||||
needs for security and anonymity. Rather than building its own content distribution
|
||||
network, Syndie is designed to run on top of existing networks, syndicating
|
||||
content through I2P Sites, Tor hidden services, Freenet freesites, normal websites,
|
||||
usenet newsgroups, email lists, RSS feeds, etc. Data published with Syndie
|
||||
is done so as to offer pseudonymous authentication to anyone reading or archiving
|
||||
it.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2ptunnel">I2PTunnel</h2>
|
||||
<p><i>{% trans dev='mihi' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
@ -1027,6 +955,25 @@ POP3 and SMTP destinations (which in turn are simply "server" instances pointing
|
||||
at POP3 and SMTP servers), as well as "client" tunnels pointing at I2P's CVS
|
||||
server, allowing anonymous development. At times people have even run "client"
|
||||
proxies to access the "server" instances pointing at an NNTP server.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2pbt">i2p-bt</h2>
|
||||
<p><i>{% trans dev='duck, et al' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans -%}
|
||||
i2p-bt is a port of the mainline python BitTorrent client to run both the
|
||||
tracker and peer communication over I2P. Tracker requests are forwarded through
|
||||
the eepproxy to I2P Sites specified in the torrent file while tracker responses
|
||||
refer to peers by their destination explicitly, allowing i2p-bt to open up
|
||||
a <a href="#app.streaming">streaming lib</a> connection to query them for
|
||||
blocks.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
In addition to i2p-bt, a port of bytemonsoon has been made to I2P, making
|
||||
a few modifications as necessary to strip any anonymity-compromising information
|
||||
from the application and to take into consideration the fact that IPs cannot
|
||||
be used for identifying peers.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2psnark">I2PSnark</h2>
|
||||
@ -1040,6 +987,40 @@ href="http://www.klomp.org/snark/">Snark</a> client
|
||||
Bundled with the I2P install, I2PSnark offers a simple anonymous BitTorrent
|
||||
client with multitorrent capabilities, exposing all of the functionality through
|
||||
a plain HTML web interface.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.robert">Robert</h2>
|
||||
<p><i>{% trans dev='sponge' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans bob=i2pconv('bob.i2p') -%}
|
||||
Robert is a Bittorrent client written in Python.
|
||||
It is hosted on <a href="http://{{ bob }}/Robert.html">http://{{ bob }}/Robert.html</a> <!-- TODO: expand -->
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.pybit">PyBit</h2>
|
||||
<p><i>{% trans dev='Blub' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans pybit='http://'+i2pconv('echelon.i2p')+'/pybit/' -%}
|
||||
PyBit is a Bittorrent client written in Python.
|
||||
It is hosted on <a href="{{ pybit }}">{{ pybit }}</a> <!-- TODO: expand -->
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2phex">I2Phex</h2>
|
||||
<p><i>{% trans dev='sirup' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans -%}
|
||||
I2Phex is a fairly direct port of the Phex Gnutella filesharing client to
|
||||
run entirely on top of I2P. While it has disabled some of Phex's functionality,
|
||||
such as integration with Gnutella webcaches, the basic file sharing and chatting
|
||||
system is fully functional.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.imule">iMule</h2>
|
||||
<p><i>{% trans dev='mkvore' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans -%}
|
||||
iMule is a fairly direct port of the aMule filesharing client
|
||||
running entirely inside I2P.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2pmail">I2Pmail/susimail</h2>
|
||||
@ -1059,9 +1040,27 @@ to delivery through the mail.i2p outproxies, which are separate from the mail.i2
|
||||
SMTP and POP3 servers - both the outproxies and inproxies communicate with
|
||||
the mail.i2p SMTP and POP3 servers through I2P itself, so compromising those
|
||||
non-anonymous locations does not give access to the mail accounts or activity
|
||||
patterns of the user.
|
||||
patterns of the user. At the moment the developers work on a decentralized
|
||||
mailsystem, called "v2mail". More information can be found on the I2P Site
|
||||
<a href="http://{{ postman }}/">{{ postman }}</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2pbote">I2P-Bote</h2>
|
||||
<p><i>{% trans dev='HungryHobo' -%}Developed by: {{ dev }}{%- endtrans %}</i></p>
|
||||
|
||||
<p>{% trans -%}
|
||||
I2P-Bote is a distributed e-mail application. It does not use the traditional
|
||||
e-mail concept of sending an e-mail to a server and retrieving it from a server.
|
||||
Instead, it uses a Kademlia Distributed Hash Table to store mails.
|
||||
One user can push a mail into the DHT, while another can request the e-mail from the DHT.
|
||||
And all the mails sent within the I2P-Bote network are automatically encrypted end-to-end. <br>
|
||||
Furthermore, I2P-Bote offers a remailer function on top of I2P, for increased high-latency anonymity.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="app.i2pmessenger">I2P-Messenger</h2>
|
||||
<p>{% trans -%}
|
||||
I2P-Messenger is an end-to-end encrypted serverless communication application.
|
||||
For communication between two users, they need to give each other their destination keys, to allow the other to connect.
|
||||
It supports file transfer and has a search for other users, based on Seedless.
|
||||
{%- endtrans %}</p>
|
||||
{% endblock %}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Index to Technical Documentation{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2025-06{% endblock %}
|
||||
{% block accuratefor %}0.9.67{% endblock %}
|
||||
{% block lastupdated %}2022-08{% endblock %}
|
||||
{% block accuratefor %}0.9.55{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans -%}
|
||||
Following is an index to the technical documentation for I2P.
|
||||
@ -19,7 +19,7 @@ The specifications linked below are currently supported in the network.
|
||||
See the <a href="{{ site_url('spec/proposals') }}">{{ _('Proposals') }}</a> page for
|
||||
specifications in discussion or development.
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
The I2P Project is committed to maintaining accurate, current documentation.
|
||||
If you find any inaccuracies in the documents linked below, please
|
||||
<a href="{{ trac }}">enter a ticket identifying the problem</a>.
|
||||
@ -122,7 +122,6 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
{% trans %}How client messages are end-to-end encrypted by the router.{% endtrans %}
|
||||
<ul>
|
||||
<li><a href="{{ spec_url('ecies') }}">{{ _('ECIES-X25519-AEAD-Ratchet encryption for destinations') }}</a></li>
|
||||
<li><a href="{{ spec_url('ecies-hybrid') }}">PQ Hybrid {{ _('ECIES-X25519-AEAD-Ratchet encryption for destinations') }}</a></li>
|
||||
<li><a href="{{ spec_url('ecies-routers') }}">{{ _('ECIES-X25519 encryption for routers') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTag encryption') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/cryptography') }}">{{ _('ElGamal and AES cryptography details') }}</a></li>
|
||||
@ -257,7 +256,7 @@ ancient (str4d)
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('zzz.i2p') }}/">{{ _('Developer forum inside I2P') }}</a>
|
||||
</li><li>
|
||||
<a href="https://i2pgit.org/I2P_Developers/i2p.i2p/issues">{{ _('Bug tracker') }}</a>
|
||||
<a href="https://i2pgit.org/i2p-hackers/i2p.i2p/issues">{{ _('Bug tracker') }}</a>
|
||||
</li><li>
|
||||
<a href="https://github.com/i2p/i2p.i2p">{{ _('I2P Source exported to GitHub') }}</a>
|
||||
</li><li>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Naming and Address Book{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2025-01{% endblock %}
|
||||
{% block accuratefor %}0.9.65{% endblock %}
|
||||
{% block lastupdated %}2023-11{% endblock %}
|
||||
{% block accuratefor %}0.9.59{% endblock %}
|
||||
{% block content %}
|
||||
<h2 id="overview">{% trans %}Overview{% endtrans %}</h2>
|
||||
|
||||
@ -168,39 +168,18 @@ Otherwise, it forwards the request to a configured HTTP outproxy.
|
||||
Thus, in practice, all HTTP (I2P Site) hostnames must end in the pseudo-Top Level Domain '.i2p'.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans i2ptld='https://datatracker.ietf.org/doc/draft-grothoff-iesg-special-use-p2p-names/',
|
||||
rfc6761='http://tools.ietf.org/html/rfc6761' -%}
|
||||
We have <a href="{{ i2ptld }}">applied to reserve the .i2p TLD</a>
|
||||
following the procedures specified in <a href="{{ rfc6761 }}">RFC 6761</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
If the router fails to resolve the hostname, the HTTP proxy returns
|
||||
an error page to the user with links to several "jump" services.
|
||||
See below for details.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h2 id="alt">.i2p.alt Domain</h2>
|
||||
We previously <a href="https://datatracker.ietf.org/doc/draft-grothoff-iesg-special-use-p2p-names/">applied to reserve the .i2p TLD</a>
|
||||
following the procedures specified in <a href="https://www.rfc-editor.org/rfc/rfc6761.html">RFC 6761</a>.
|
||||
However, this application and all others were rejected, and RFC 6761 was declared a "mistake".
|
||||
</p>
|
||||
<p>
|
||||
After many years of work by the GNUnet team and others, the .alt domain was reserved as a special-use TLD
|
||||
in <a href="https://www.rfc-editor.org/rfc/rfc9476.html">RFC 9476</a> as of late 2023.
|
||||
While there are no official registrars sanctioned by IANA, we have registered the .i2p.alt domain
|
||||
with the primary unofficial registrar <a href="https://gana.gnunet.org/dot-alt/dot_alt.html">GANA</a>.
|
||||
This does not prevent others from using the domain, but it should help discourage it.
|
||||
</p>
|
||||
<p>
|
||||
One benefit to the .alt domain is that, in theory, DNS resolvers will not forward .alt requests
|
||||
once they update to comply with RFC 9476, and that will prevent DNS leaks.
|
||||
For compatibility with .i2p.alt hostnames, I2P software and services should be updated to handle
|
||||
these hostnames by stripping off the .alt TLD.
|
||||
These updates are scheduled for the first half of 2024.
|
||||
</p>
|
||||
<p>
|
||||
At this time, there are no plans to make .i2p.alt the preferred form for display and interchange of I2P hostnames.
|
||||
This is a topic for further research and discussion.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h2 id="addressbook">{% trans %}Address Book{% endtrans %}</h2>
|
||||
<h3>{% trans %}Incoming Subscriptions and Merging{% endtrans %}</h3>
|
||||
|
||||
@ -300,15 +279,7 @@ Base32 hostnames (*.b32.i2p) are reserved for base 32 use and so are not allowed
|
||||
|
||||
<li>{% trans -%}
|
||||
Certain hostnames reserved for project use are not allowed
|
||||
(proxy.i2p, router.i2p, console.i2p, mail.i2p, *.proxy.i2p, *.router.i2p, *.console.i2p, *.mail.i2p, and others)
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>{% trans -%}
|
||||
Hostnames starting with 'www.' are discouraged and are rejected by some registration services.
|
||||
Some addressbook implementations automatically strip 'www.' prefixes from lookups.
|
||||
So registring 'www.example.i2p' is unnecessary,
|
||||
and registering a different destination for 'www.example.i2p' and 'example.i2p'
|
||||
will make 'www.example.i2p' unreachable for some users.
|
||||
(proxy.i2p, router.i2p, console.i2p, *.proxy.i2p, *.router.i2p, *.console.i2p, and others)
|
||||
{%- endtrans %}</li>
|
||||
|
||||
<li>{% trans -%}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Ports Used by I2P{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-02{% endblock %}
|
||||
{% block accuratefor %}0.9.62{% endblock %}
|
||||
{% block lastupdated %}2022-08{% endblock %}
|
||||
{% block accuratefor %}0.9.55{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans -%}
|
||||
@ -11,7 +11,7 @@ and some typical related applications.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans faq=site_url('faq') -%}
|
||||
Note that many of these are not installed or enabled by default.
|
||||
Note that many of these are not enabled by default.
|
||||
There is more information in <a href="{{ faq }}#ports">the FAQ</a>.
|
||||
See also the documentation for individual plugins.
|
||||
Plugin authors please add any ports you use here.
|
||||
@ -22,8 +22,7 @@ in the 767x range.
|
||||
<table>
|
||||
<tr><th>Port</th><th>Usage</th></tr>
|
||||
<tr><td>123</td><td>SNTP</td></tr>
|
||||
<tr><td>1488</td><td>XD client web UI (old)</td>
|
||||
<tr><td>1776</td><td>XD client web UI (new)</td>
|
||||
<tr><td>1488</td><td>XD client web UI</td>
|
||||
<tr><td>1900</td><td>UPnP SSDP UDP multicast listener</td>
|
||||
<tr><td>2827</td><td>BOB Bridge</td></tr>
|
||||
<tr><td>3456</td><td>Tahoe-LAFS-Controller Plugin</td></tr>
|
||||
@ -35,7 +34,6 @@ in the 767x range.
|
||||
<tr><td>6667</td><td>IRC Proxy (alt)</td></tr>
|
||||
<tr><td>6668</td><td>IRC Proxy</td></tr>
|
||||
<tr><td>6669</td><td>IRC Proxy (alt)</td></tr>
|
||||
<tr><td>7070</td><td>i2pd console</td></tr>
|
||||
<tr><td>7644</td><td>HTTP Proxy (I2P Browser mode)</td></tr>
|
||||
<tr><td>7647</td><td>Console (I2P Browser mode)</td></tr>
|
||||
<tr><td>7650</td><td>I2PControl Plugin</td></tr>
|
||||
@ -46,7 +44,7 @@ in the 767x range.
|
||||
<tr><td>7655</td><td>SAM Bridge (UDP)</td></tr>
|
||||
<tr><td>7656</td><td>SAM Bridge (TCP)</td></tr>
|
||||
<tr><td>7657</td><td>Router Console</td></tr>
|
||||
<tr><td>7658</td><td>I2P Site (Jetty)</td></tr>
|
||||
<tr><td>7658</td><td>I2P Site</td></tr>
|
||||
<tr><td>7659</td><td>SMTP Proxy</td></tr>
|
||||
<tr><td>7660</td><td>POP3 Proxy</td></tr>
|
||||
<tr><td>7661</td><td>Pebble Plugin</td></tr>
|
||||
@ -59,7 +57,6 @@ in the 767x range.
|
||||
<tr><td>7668</td><td>I2P Site SSL</td></tr>
|
||||
<tr><td>7669</td><td>Garlic Farm</td></tr>
|
||||
<tr><td>7670</td><td>Git SSH</td></tr>
|
||||
<tr><td>7672</td><td>Railroad Plugin</td></tr>
|
||||
<tr><td></td><td><i>{% trans %}recommended spot for new plugins/applications{% endtrans %}</i></td></tr>
|
||||
<tr><td>7680</td><td>don't use - Windows Delivery Optimization</td></tr>
|
||||
<tr><td>8002</td><td>I2PSnark (standalone install only)</td></tr>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}I2CP{% endblock %}
|
||||
{% block lastupdated %}2025-04{% endblock %}
|
||||
{% block accuratefor %}0.9.66{% endblock %}
|
||||
{% block lastupdated %}2023-10{% endblock %}
|
||||
{% block accuratefor %}0.9.59{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans -%}
|
||||
The I2P Client Protocol (I2CP) exposes a strong separation of concerns between
|
||||
@ -63,15 +63,13 @@ through an internal JVM interface.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||
Some router and client implementations may also support external connections over SSL,
|
||||
as configured by the i2cp.SSL=true option.
|
||||
The router also supports external connections over SSL.
|
||||
While SSL is not the default, it is strongly recommended for any traffic that may
|
||||
be exposed to the open Internet. The authorization user/password (if any), the
|
||||
<a href="{{ commonstructures }}#type_PrivateKey">Private Key</a> and
|
||||
<a href="{{ commonstructures }}#type_SigningPrivateKey">Signing Private Key</a> for the
|
||||
<a href="{{ commonstructures }}#struct_Destination">Destination</a>
|
||||
are all transmitted in-the-clear unless SSL is enabled.
|
||||
Some router and client implementations may also support external connections over domain sockets.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{% trans %}I2CP Protocol Specification{% endtrans %}</h2>
|
||||
@ -729,7 +727,7 @@ See proposal 123.
|
||||
<td>
|
||||
The base 64 of the client name (ignored, UI use only),
|
||||
followed by a ':', followed by the base 64 of the private
|
||||
key to use for PSK per-client auth. nnn starts with 0.
|
||||
key to use for PSK per-client auth. nnn starts with 0
|
||||
See proposal 123.
|
||||
</td>
|
||||
</tr>
|
||||
@ -760,21 +758,6 @@ See proposals 123, 144, and 145.
|
||||
<td>{% trans %}For encrypted leasesets. Base 64 SessionKey (44 characters){% endtrans %}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>i2cp.leaseSetOption.nnn
|
||||
<td>0.9.66</td>
|
||||
<td>srvKey=srvValue
|
||||
<td>
|
||||
<td>
|
||||
<td>
|
||||
A service record to be placed in the LeaseSet2 options.
|
||||
Example:
|
||||
"_smtp._tcp=1 86400 0 0 25 ...b32.i2p"
|
||||
nnn starts with 0.
|
||||
See proposal 167.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>i2cp.leaseSetPrivateKey
|
||||
<td>0.9.18</td>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Protocol Stack{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-01{% endblock %}
|
||||
{% block accuratefor %}0.9.61{% endblock %}
|
||||
{% block lastupdated %}2021-12{% endblock %}
|
||||
{% block accuratefor %}0.9.52{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans docs=site_url('docs') -%}
|
||||
@ -86,7 +86,8 @@ However, each of these layers adds additional functionality, to allow applicatio
|
||||
<br />
|
||||
<a href="{{ site_url('docs/api/i2ptunnel') }}">I2PTunnel</a>
|
||||
<br />
|
||||
<a href="{{ site_url('docs/api/samv3') }}">SAMv3</a>
|
||||
<a href="{{ site_url('docs/api/sam') }}">SAM</a>/<a href="{{ site_url('docs/api/samv2') }}">SAMv2</a>/<a href="{{ site_url('docs/api/samv3') }}">SAMv3</a>(*),
|
||||
<a href="{{ site_url('docs/api/bob') }}">BOB</a>
|
||||
</li>
|
||||
<li>
|
||||
{% trans %}<b>I2P Application Proxy Layer:</b> proxy systems.{% endtrans %}
|
||||
|
@ -1,18 +1,12 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Secure Semireliable UDP{% endtrans %} (SSU){% endblock %}
|
||||
{% block lastupdated %}2025-01{% endblock %}
|
||||
{% block accuratefor %}0.9.64{% endblock %}
|
||||
{% block lastupdated %}2022-07{% endblock %}
|
||||
{% block accuratefor %}0.9.54{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>
|
||||
<b>DEPRECATED</b> - SSU has been replaced by SSU2.
|
||||
SSU support was removed from i2pd in release 2.44.0 (API 0.9.56) 2022-11.
|
||||
SSU support was removed from Java I2P in release 2.4.0 (API 0.9.61) 2023-12.
|
||||
</p>
|
||||
|
||||
<p>{% trans transports=site_url('docs/transport'), ntcp=site_url('docs/transport/ntcp'), ntcp2=site_url('docs/spec/ntcp2') -%}
|
||||
SSU (also called "UDP" in much of the I2P documentation and user interfaces)
|
||||
was one of two <a href="{{ transports }}">transports</a> implemented in I2P.
|
||||
is one of two <a href="{{ transports }}">transports</a> currently implemented in I2P.
|
||||
The other is <a href="{{ ntcp2 }}">NTCP2</a>.
|
||||
Support for <a href="{{ ntcp }}">NTCP</a> has been removed.
|
||||
{%- endtrans %}</p>
|
||||
|
@ -1036,8 +1036,8 @@ either through our IRC network, IRC2P, or on Freenode.{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans -%}Our Bugtracker:{%- endtrans %}
|
||||
<ul>
|
||||
<li>{% trans -%}Non-private internet:{%- endtrans %} <a href="https://i2pgit.org/I2P_Developers/i2p.i2p/issues">https://i2pgit.org/I2P_Developers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}On I2P:{%- endtrans %} <a href="http://git.idk.i2p/I2P_Developers/i2p.i2p/issues">http://git.idk.i2p/I2P_Developers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}Non-private internet:{%- endtrans %} <a href="https://i2pgit.org/i2p-hackers/i2p.i2p/issues">https://i2pgit.org/i2p-hackers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}On I2P:{%- endtrans %} <a href="http://git.idk.i2p/i2p-hackers/i2p.i2p/issues">http://git.idk.i2p/i2p-hackers/i2p.i2p/issues</a></li>
|
||||
</ul>
|
||||
<li>{% trans -%}Our forums:{%- endtrans %} <a href="http://{{ i2pconv('i2pforum.i2p') }}/">{{ i2pconv('i2pforum.i2p') }}</a></li>
|
||||
<li>{% trans -%}You may paste any interesting logs to a paste service such as the non-private internet services listed on the
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('Developer Guidelines and Coding Style') }}{% endblock %}
|
||||
{% block lastupdated %}2025-03{% endblock %}
|
||||
{% block lastupdated %}2022-01{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans newdevs=site_url('get-involved/guides/new-developers') -%}
|
||||
Read the <a href="{{ newdevs }}">new developers guide</a> first.
|
||||
@ -34,8 +34,8 @@ the checkin deadline for a release.
|
||||
|
||||
<h3>{{ _('Release Cycle') }}</h3>
|
||||
<p>
|
||||
The normal release cycle is 10-16 weeks, four releases a year.
|
||||
Following are the approximate deadlines within a typical 13-week cycle.
|
||||
The normal release cycle is 6-12 weeks.
|
||||
Following are the approximate deadlines within a typical 8-week cycle.
|
||||
Actual deadlines for each release are set by the release manager after consultation with the full team.
|
||||
</p>
|
||||
|
||||
@ -87,8 +87,8 @@ Check in some small changes and see how it goes.
|
||||
<li>{% trans -%}
|
||||
Test your changes before checking them in.
|
||||
If you prefer the checkin-before-test development model,
|
||||
use your own development branch in your own account,
|
||||
and create an MR once the work is done.
|
||||
use your own development branch
|
||||
and propagate back to i2p.i2p once it is working well.
|
||||
Do not break the build. Do not cause regressions.
|
||||
In case you do (it happens), please do not vanish for a long period after
|
||||
you push your change.
|
||||
@ -99,30 +99,17 @@ to know whether your change was tested or not, add a checkin comment to history.
|
||||
and increment the build revision in RouterVersion.java.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Do not check in major changes into the main i2p.i2p branch late in the release cycle.
|
||||
If a project will take you more than a couple days, create your own branch in git,
|
||||
in your own account, and do the development there so you do not block releases.
|
||||
Ensure that you 'git pull' to the latest revision before you check in and push.
|
||||
If you inadvertently diverge, merge and push as soon as possible.
|
||||
Don't routinely make others merge for you.
|
||||
{%- endtrans %}</li>
|
||||
<li>{% trans -%}
|
||||
Do not check in major changes into the main i2p.i2p branch late in the release cycle.
|
||||
If a project will take you more than a couple days, create your own branch in git
|
||||
and do the development there so you do not block releases.
|
||||
{%- endtrans %}</li>
|
||||
<li>
|
||||
For big changes (generally speaking, more than 100 lines, or touching more than three files),
|
||||
check it into a new branch on your own gitlab account, create an MR, and assign a reviewer.
|
||||
Assign the MR to yourself. Merge the MR yourself once the reviewer approves it.
|
||||
</li>
|
||||
<li>
|
||||
Do not create WIP branches in the main I2P_Developers account (except for i2p.www).
|
||||
WIP belongs in your own account. When the work is done, create an MR.
|
||||
The only branches in the main account should be for true forks, like a point release.
|
||||
</li>
|
||||
<li>
|
||||
Do development in a transparent fashion and with the community in mind.
|
||||
Checkin often. Checkin or merge into the main branch
|
||||
as frequently as possible, given the guidelines above.
|
||||
If you are working on some big project in your own branch/account,
|
||||
let people know so they may follow along and review/test/comment.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>{{ _('Coding Style') }}</h3>
|
||||
<ul>
|
||||
<li>{% trans -%}
|
||||
@ -290,7 +277,7 @@ Include the license and source information in the checkin comment.
|
||||
|
||||
<h3>{{ _('Bugs') }}</h3>
|
||||
<ul>
|
||||
<li>{% trans trac=i2pconv('git.idk.i2p') -%}
|
||||
<li>{% trans trac=i2pconv('trac.i2p2.i2p') -%}
|
||||
Managing issues are everybody's job, please help.
|
||||
Monitor {{ Gitlab }} for issues you can help with.
|
||||
Comment on, fix, and close issues if you can.
|
||||
|
@ -65,7 +65,7 @@ Install <a href="{{ git_url }}">Git</a>.
|
||||
</li>
|
||||
<li><strong><a href="https://i2pgit.org">{% trans %}Outside I2P - (https://i2pgit.org){% endtrans %}</a></strong>
|
||||
</li>
|
||||
<code>git clone https://i2pgit.org/I2P_Developers/i2p.i2p.git</code>
|
||||
<code>git clone https://i2pgit.org/i2p-hackers/i2p.i2p.git</code>
|
||||
</ul>
|
||||
|
||||
<p>The read-only mirror is also still available at github.</p>
|
||||
@ -100,7 +100,7 @@ see the <a href="{{ apps }}">application development guide</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="development-ideas">{% trans %}Development ideas{% endtrans %}</h2>
|
||||
<p>{% trans todo=site_url('get-involved/todo'), trac='https://i2pgit.org/I2P_Developers/i2p.i2p/issues' -%}
|
||||
<p>{% trans todo=site_url('get-involved/todo'), trac='https://i2pgit.org/i2p-hackers/i2p.i2p/issues' -%}
|
||||
See <a href="{{ todo }}">the project TODO list</a> or
|
||||
<a href="{{ trac }}">the issue list on GitLab</a>
|
||||
for ideas.
|
||||
|
@ -26,6 +26,16 @@ Optional:
|
||||
<li>IPv6</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans -%}
|
||||
When your setup is complete and ready for testing, we will need the HTTPS URL,
|
||||
the SSL public key certificate (only if selfsigned), and the su3 public key certificate.
|
||||
After testing is complete, these will be added to the hardcoded entries in the Java and C++ routers in the next release,
|
||||
and you will start seeing traffic.
|
||||
We also will need your email address so we may continue to contact you about reseed administration issues.
|
||||
The email will not be made public but will be known to the other reseed operators.
|
||||
You should expect that your nick or name and its association with that URL or IP will become public.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h3>{% trans %}Information Required{% endtrans %}</h3>
|
||||
|
||||
<p>{% trans -%}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('How to Set up a Reseed Server') }}{% endblock %}
|
||||
{% block lastupdated %}2024-12{% endblock %}
|
||||
{% block lastupdated %}2023-01{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h2>{% trans %}General Information{% endtrans %}</h2>
|
||||
@ -140,11 +140,11 @@ zzz.i2p
|
||||
. {% trans %}These will allow I2P users to authenticate your reseed services and secure the I2P network.{% endtrans %}
|
||||
</p>
|
||||
<p>
|
||||
Contact us via email zzz at mail.i2p.
|
||||
Provide us with details about your new reseed server:
|
||||
{% trans %}Contact us via email zzz at mail.i2p (alternatively, post in the reseed section on the zzz.i2p forum)
|
||||
Provide us with details about your new reseed server:{% endtrans %}
|
||||
<ul>
|
||||
<li>{% trans %}Reseed website URL{% endtrans %}</li>
|
||||
<li>Public SSL certificate (only required if selfsigned)</li>
|
||||
<li>{% trans %}Public SSL certificate{% endtrans %}</li>
|
||||
<li>{% trans %}Public reseed su3 certificate{% endtrans %}</li>
|
||||
<li>{% trans %}Your contact email{% endtrans %}</li>
|
||||
<li>{% trans %}A statement that you agree to the privacy policy above{% endtrans %}</li>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %} {{ _('Roadmap') }}{% endblock %}
|
||||
{% block lastupdated %}2025-04{% endblock %} {% block content %}
|
||||
{% block lastupdated %}2022-11{% endblock %} {% block content %}
|
||||
|
||||
<p>
|
||||
This is the official project roadmap for the desktop and Android Java I2P releases only. Some related tasks for resources such as the website and plugins may be included.
|
||||
@ -9,386 +9,40 @@
|
||||
For details and discussion on specific items, search on gitlab or zzz.i2p. For contents of past releases, see the release notes. For other project goals, see the meeting notes.
|
||||
</p>
|
||||
<p>
|
||||
We do not maintain separate unstable and stable branches or releases. We have a single, stable release path. Our typical release cycle is about 13 weeks.
|
||||
We do not maintain separate unstable and stable branches or releases. We have a single, stable release path. Our normal release cycle is 13 weeks, with releases in February, May, August, and November.
|
||||
</p>
|
||||
<p>
|
||||
Older releases are at the bottom of the page.
|
||||
</p>
|
||||
|
||||
|
||||
<h2 id="2.10.0">2.10.0 (API 0.9.67)</h2>
|
||||
<p><b>Target release: Late August 2025</b></p>
|
||||
<h2 id="2.4.0">2.4.0 (API 0.9.60)</h2>
|
||||
<p><b>Target release: September 2023</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
UDP tracker support (prop. 160)
|
||||
NetDB context management
|
||||
</li>
|
||||
<li>
|
||||
Implement LS service record parameter (prop. 167)
|
||||
</li>
|
||||
<li>
|
||||
Continue work on PQ (prop. 169);
|
||||
Start checking in MLKEM parts of PQ (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Tunnel build bandwidth parameters (prop. 168)
|
||||
Part 2 (handling)
|
||||
</li>
|
||||
<li>
|
||||
Continue work on per-tunnel throttling
|
||||
</li>
|
||||
<li>
|
||||
Stat/graph subsystem cleanup and make prometheus-friendly
|
||||
</li>
|
||||
<li>
|
||||
Tomcat update
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.9.0">2.9.0 (API 0.9.66)</h2>
|
||||
<p><b>Released: June 2, 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Netdb map
|
||||
</li>
|
||||
<li>
|
||||
Implement Datagram2, Datagram3 (prop. 163)
|
||||
</li>
|
||||
<li>
|
||||
Start work on LS service record parameter (prop. 167)
|
||||
</li>
|
||||
<li>
|
||||
Start work on PQ (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Continue work on per-tunnel throttling
|
||||
</li>
|
||||
<li>
|
||||
Tunnel build bandwidth parameters (prop. 168)
|
||||
Part 1 (sending)
|
||||
</li>
|
||||
<li>
|
||||
Use /dev/random for PRNG by default on Linux
|
||||
</li>
|
||||
<li>
|
||||
Remove redundant LS render code
|
||||
</li>
|
||||
<li>
|
||||
Display changelog in HTML
|
||||
</li>
|
||||
<li>
|
||||
Reduce HTTP server thread usage
|
||||
</li>
|
||||
<li>
|
||||
Fix auto-floodfill enrollment
|
||||
</li>
|
||||
<li>
|
||||
Wrapper update to 3.5.60
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="2.8.2">2.8.2 (API 0.9.65)</h2>
|
||||
<p><b>Released: March 29, 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Fix SHA256 corruption bug
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="2.8.1">2.8.1 (API 0.9.65)</h2>
|
||||
<p><b>Released: March 17, 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Fix installer failure on Java 21+
|
||||
</li>
|
||||
<li>
|
||||
Fix "loopback" bug
|
||||
</li>
|
||||
<li>
|
||||
Fix tunnel tests for outbound client tunnels
|
||||
</li>
|
||||
<li>
|
||||
Fix installing to paths with spaces
|
||||
</li>
|
||||
<li>
|
||||
Update outdated Docker container and container libraries
|
||||
</li>
|
||||
<li>
|
||||
Console notification bubbles
|
||||
</li>
|
||||
<li>
|
||||
SusiDNS sort-by-latest
|
||||
</li>
|
||||
<li>
|
||||
Use SHA256 pool in Noise
|
||||
</li>
|
||||
<li>
|
||||
Console dark theme fixes and improvements
|
||||
</li>
|
||||
<li>
|
||||
.i2p.alt support
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="2.8.0">2.8.0 (API 0.9.65)</h2>
|
||||
<p><b>Released: February 3, 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
RouterInfo publishing improvements
|
||||
</li>
|
||||
<li>
|
||||
Improve SSU2 ACK efficiency
|
||||
</li>
|
||||
<li>
|
||||
Improve SSU2 handling of dup relay messages
|
||||
</li>
|
||||
<li>
|
||||
Faster / variable lookup timeouts
|
||||
</li>
|
||||
<li>
|
||||
LS expiration improvements
|
||||
</li>
|
||||
<li>
|
||||
Change symmetric NAT cap
|
||||
</li>
|
||||
<li>
|
||||
Enforce POST in more forms
|
||||
</li>
|
||||
<li>
|
||||
SusiDNS dark theme fixes
|
||||
</li>
|
||||
<li>
|
||||
Bandwidth test cleanups
|
||||
</li>
|
||||
<li>
|
||||
New Gan Chinese translation
|
||||
</li>
|
||||
<li>
|
||||
Add Kurdish option to UI
|
||||
</li>
|
||||
<li>
|
||||
New Jammy build to handle Jetty API change
|
||||
</li>
|
||||
<li>
|
||||
Izpack 5.2.3
|
||||
</li>
|
||||
<li>
|
||||
rrd4j 3.10
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.7.0">2.7.0 (API 0.9.64)</h2>
|
||||
<p><b>Released: October 8, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
i2ptunnel HTTP server reduce thread usage
|
||||
</li>
|
||||
<li>
|
||||
Generic UDP Tunnels in I2PTunnel
|
||||
</li>
|
||||
<li>
|
||||
Browser Proxy in I2PTunnel(Proposal 166)
|
||||
</li>
|
||||
<li>
|
||||
Website Migration
|
||||
</li>
|
||||
<li>
|
||||
Fix for tunnels going yellow
|
||||
</li>
|
||||
<li>
|
||||
Console /netdb refactoring
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.6.1">2.6.1 (API 0.9.63)</h2>
|
||||
<p><b>Released: August 6, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Fix iframe size issues in console
|
||||
</li>
|
||||
<li>
|
||||
Convert graphs to SVG
|
||||
</li>
|
||||
<li>
|
||||
Bundle translation status report in console
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.6.0">2.6.0 (API 0.9.63)</h2>
|
||||
<p><b>Released: July 19, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Reduce memory usage for netdb
|
||||
</li>
|
||||
<li>
|
||||
Continue removing SSU1 code
|
||||
</li>
|
||||
<li>
|
||||
Fix i2psnark temp file leaks and stalls
|
||||
</li>
|
||||
<li>
|
||||
More efficient PEX in i2psnark
|
||||
</li>
|
||||
<li>
|
||||
JS refresh of graphs in console
|
||||
</li>
|
||||
<li>
|
||||
Graph rendering improvements
|
||||
</li>
|
||||
<li>
|
||||
Susimail JS search
|
||||
</li>
|
||||
<li>
|
||||
More efficient handling of messages at OBEP
|
||||
</li>
|
||||
<li>
|
||||
More efficient lookup of local destinations in I2CP
|
||||
</li>
|
||||
<li>
|
||||
Fix JS variable scoping issues and concurrency
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.5.2">2.5.2 (API 0.9.62)</h2>
|
||||
<p><b>Released: May 15, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
HTTP truncation fix
|
||||
</li>
|
||||
<li>
|
||||
Publish G cap if symmetric natted
|
||||
</li>
|
||||
<li>
|
||||
rrd4j 3.9.1-preview
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.5.1">2.5.1 (API 0.9.62)</h2>
|
||||
<p><b>Released: May 6, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
NetDB DDoS mitigations
|
||||
</li>
|
||||
<li>
|
||||
Add Tor blocklist
|
||||
</li>
|
||||
<li>
|
||||
susimail fixes
|
||||
</li>
|
||||
<li>
|
||||
susimail search
|
||||
</li>
|
||||
<li>
|
||||
Continue removing SSU1 code
|
||||
</li>
|
||||
<li>
|
||||
Tomcat 9.0.88
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.5.0">2.5.0 (API 0.9.62)</h2>
|
||||
<p><b>Released: April 8, 2024</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Console iframe improvements
|
||||
</li>
|
||||
<li>
|
||||
Redesign i2psnark bandwidth limiter
|
||||
</li>
|
||||
<li>
|
||||
Javascript drag-and-drop for i2psnark and susimail
|
||||
</li>
|
||||
<li>
|
||||
i2ptunnel SSL error handling improvements
|
||||
</li>
|
||||
<li>
|
||||
i2ptunnel persistent HTTP connection support
|
||||
</li>
|
||||
<li>
|
||||
Start removing SSU1 code
|
||||
</li>
|
||||
<li>
|
||||
SSU2 relay tag request handling improvements
|
||||
</li>
|
||||
<li>
|
||||
SSU2 peer test fixes
|
||||
</li>
|
||||
<li>
|
||||
susimail initial loading speedup
|
||||
</li>
|
||||
<li>
|
||||
susimail javascript markdown for plain text emails
|
||||
</li>
|
||||
<li>
|
||||
susimail HTML email support
|
||||
</li>
|
||||
<li>
|
||||
susimail fixes and improvements
|
||||
</li>
|
||||
<li>
|
||||
tunnnel peer selection adjustments
|
||||
</li>
|
||||
<li>
|
||||
Update RRD4J to 3.9
|
||||
</li>
|
||||
<li>
|
||||
Update gradlew to 8.5
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="2.4.0">2.4.0 (API 0.9.61)</h2>
|
||||
<p><b>Released: December 18, 2023</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
NetDB context management/Segmented NetDB
|
||||
Streaming replay fix
|
||||
</li>
|
||||
<li>
|
||||
Handle congestion capabilities by deprioritizing overloaded routers
|
||||
</li>
|
||||
<li>
|
||||
"Install Plugin from File" command-line option
|
||||
</li>
|
||||
<li>
|
||||
Generic UDP Tunnels in HSM
|
||||
</li>
|
||||
<li>
|
||||
Revive Android helper library
|
||||
</li>
|
||||
<li>
|
||||
i2psnark local torrent file selector
|
||||
</li>
|
||||
<li>
|
||||
NetDB lookup handler fixes
|
||||
</li>
|
||||
<li>
|
||||
Disable SSU1
|
||||
</li>
|
||||
<li>
|
||||
Ban routers publishing in the future
|
||||
</li>
|
||||
<li>
|
||||
SAM fixes
|
||||
</li>
|
||||
<li>
|
||||
susimail fixes
|
||||
</li>
|
||||
<li>
|
||||
UPnP fixes
|
||||
Website Migration
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="2.3.0">2.3.0 (API 0.9.59)</h2>
|
||||
<p><b>Released: June 28, 2023</b></p>
|
||||
<p><b>Target release: June 2023</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Tunnel peer selection improvements
|
||||
@ -410,16 +64,8 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="2.2.1">2.2.1 (API 0.9.58)</h2>
|
||||
<p><b>Released: April 12, 2023</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Packaging fixes
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="2.2.0">2.2.0 (API 0.9.58)</h2>
|
||||
<p><b>Released: March 13, 2023</b></p>
|
||||
<p><b>Target release: April 2023</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Tunnel peer selection improvements
|
||||
|
@ -1,12 +1,14 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('Vulnerability Response Process') }}{% endblock %}
|
||||
{% block lastupdated %}2023-04{% endblock %}
|
||||
{% block lastupdated %}2020-06{% endblock %}
|
||||
{% block content_id %}vrp{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans %}
|
||||
This process is subject to change. Please refer to this page for the current VRP.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans %}This page was last updated April 2023.{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans %}Researchers: during your study and network testing, we ask that you refrain from the following: - Performing active exploits or Denial of Service attacks on the
|
||||
I2P network - Performing social engineering on I2P team and community members - Performing any physical or electronic attempts against I2P property and/or data
|
||||
centers{%- endtrans %}</p>
|
||||
|
@ -22,7 +22,7 @@ in during the course of development. Periodic reviews are conducted to update
|
||||
the "accurate for" information.
|
||||
</li></ul>
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
The I2P Project is committed to maintaining accurate, current documentation.
|
||||
If you find any inaccuracies in the documents linked below, please
|
||||
<a href="{{ trac }}">enter a ticket identifying the problem</a>.
|
||||
@ -55,6 +55,7 @@ If you find any inaccuracies in the documents linked below, please
|
||||
Current specifications: These may eventually be migrated to the new format.
|
||||
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTags') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/api/i2pcontrol') }}">I2PControl</a></li>
|
||||
<li><a href="{{ site_url('docs/api/samv3') }}">SAM v3</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/bittorrent') }}">{{ _('Bittorrent') }}</a></li>
|
||||
@ -64,14 +65,8 @@ Current specifications: These may eventually be migrated to the new format.
|
||||
Obsolete specifications:
|
||||
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/transport/ntcp') }}">NTCP</a></li>
|
||||
<li><a href="{{ site_url('docs/api/bob') }}">BOB</a></li>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTags') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/transport/ntcp') }}">NTCP 1</a></li>
|
||||
<li><a href="{{ site_url('docs/api/sam') }}">SAM v1</a></li>
|
||||
<li><a href="{{ site_url('docs/api/samv2') }}">SAM v2</a></li>
|
||||
<li><a href="{{ site_url('docs/transport/ssu') }}">SSU 1 (overview)</a></li>
|
||||
<li><a href="{{ spec_url('ssu') }}">SSU 1 (spec)</a></li>
|
||||
<li><a href="{{ spec_url('tunnel-creation') }}">Tunnel Creation (ElGamal)</a></li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -3,8 +3,8 @@ Common structures Specification
|
||||
===============================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
:lastupdated: 2023-01
|
||||
:accuratefor: 0.9.57
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -84,24 +84,15 @@ X25519 keys are supported in RouterIdentities as of release 0.9.48.
|
||||
|
||||
|
||||
|
||||
================ ================= ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
================ ================= ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 64 TBD Reserved, see proposal 145
|
||||
P384 96 TBD Reserved, see proposal 145
|
||||
P521 132 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
MLKEM512_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM512 800 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768 1184 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024 1568 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM512_CT 768 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768_CT 1088 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024_CT 1568 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
================ ================= ====== =====
|
||||
======= ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
======= ============== ====== =====
|
||||
ElGamal 256 All Router Identities and Destinations
|
||||
P256 64 TBD Reserved, see proposal 145
|
||||
P384 96 TBD Reserved, see proposal 145
|
||||
P521 132 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
======= ============== ====== =====
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/PublicKey.html
|
||||
|
||||
@ -125,21 +116,15 @@ The default type is ElGamal. As of release
|
||||
0.9.38, other types may be supported, depending on context.
|
||||
Keys are big-endian unless otherwise noted.
|
||||
|
||||
================ ================== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
================ ================== ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 32 TBD Reserved, see proposal 145
|
||||
P384 48 TBD Reserved, see proposal 145
|
||||
P521 66 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
MLKEM512_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM512 1632 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768 2400 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024 3168 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
================ ================== ====== =====
|
||||
======= ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
======= ============== ====== =====
|
||||
ElGamal 256 All Router Identities and Destinations
|
||||
P256 32 TBD Reserved, see proposal 145
|
||||
P384 48 TBD Reserved, see proposal 145
|
||||
P521 66 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
======= ============== ====== =====
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/PrivateKey.html
|
||||
|
||||
@ -176,12 +161,12 @@ Certificate of a Destination. The default type is DSA_SHA1. As of release
|
||||
====================== ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
====================== ============== ====== =====
|
||||
DSA_SHA1 128 Deprecated for Router Identities as of 09.58; discouraged for Destinations
|
||||
ECDSA_SHA256_P256 64 0.9.12 Deprecated Older Destinations
|
||||
ECDSA_SHA384_P384 96 0.9.12 Deprecated Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 132 0.9.12 Deprecated Rarely used for Destinations
|
||||
RSA_SHA256_2048 256 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 384 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
DSA_SHA1 128 Legacy Router Identities and Destinations
|
||||
ECDSA_SHA256_P256 64 0.9.12 Recent Destinations
|
||||
ECDSA_SHA384_P384 96 0.9.12 Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 132 0.9.12 Rarely used for Destinations
|
||||
RSA_SHA256_2048 256 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 384 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA512_4096 512 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 32 0.9.25 Offline signing, never used for Router Identities or Destinations
|
||||
@ -216,12 +201,12 @@ As of release 0.9.12, other types may be supported, depending on context.
|
||||
====================== ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
====================== ============== ====== =====
|
||||
DSA_SHA1 20 Deprecated for Router Identities as of 09.58; discouraged for Destinations
|
||||
ECDSA_SHA256_P256 32 0.9.12 Deprecated Older Destinations
|
||||
ECDSA_SHA384_P384 48 0.9.12 Deprecated Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 66 0.9.12 Deprecated Rarely used for Destinations
|
||||
RSA_SHA256_2048 512 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 768 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
DSA_SHA1 20 Legacy Router Identities and Destinations
|
||||
ECDSA_SHA256_P256 32 0.9.12 Recent Destinations
|
||||
ECDSA_SHA384_P384 48 0.9.12 Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 66 0.9.12 Rarely used for Destinations
|
||||
RSA_SHA256_2048 512 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 768 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA512_4096 1024 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 32 0.9.25 Offline signing, never used for Router Identities or Destinations
|
||||
@ -257,12 +242,12 @@ depending on context.
|
||||
====================== ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
====================== ============== ====== =====
|
||||
DSA_SHA1 40 Deprecated for Router Identities as of 09.58; discouraged for Destinations
|
||||
ECDSA_SHA256_P256 64 0.9.12 Deprecated Older Destinations
|
||||
ECDSA_SHA384_P384 96 0.9.12 Deprecated Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 132 0.9.12 Deprecated Rarely used for Destinations
|
||||
RSA_SHA256_2048 256 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 384 0.9.12 Deprecated Offline signing, never used for Router Identities or Destinations
|
||||
DSA_SHA1 40 Legacy Router Identities and Destinations
|
||||
ECDSA_SHA256_P256 64 0.9.12 Recent Destinations
|
||||
ECDSA_SHA384_P384 96 0.9.12 Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 132 0.9.12 Rarely used for Destinations
|
||||
RSA_SHA256_2048 256 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 384 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA512_4096 512 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 64 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 64 0.9.25 Offline signing, never used for Router Identities or Destinations
|
||||
@ -372,9 +357,8 @@ specifying the size of the certificate payload, then that many bytes.
|
||||
Notes
|
||||
`````
|
||||
* For `Router Identities`_, the Certificate is always NULL through version
|
||||
0.9.15. As of 0.9.16, a Key Certificate is used to specify the
|
||||
key types. As of 0.9.48, X25519 encryption public key types
|
||||
are allowed. See below.
|
||||
0.9.15. As of 0.9.16, a Key Certificate may be used to specify the signing
|
||||
public key type. See below.
|
||||
|
||||
* For `Garlic Cloves`_, the Certificate is always NULL, no others are currently
|
||||
implemented.
|
||||
@ -401,11 +385,11 @@ The following certificate types are defined:
|
||||
Type Type Code Payload Length Total Length Notes
|
||||
======== ========= ============== ============ =====
|
||||
Null 0 0 3
|
||||
HashCash 1 varies varies Deprecated, unused. Payload contains an ASCII colon-separated hashcash string.
|
||||
Hidden 2 0 3 Deprecated, unused. Hidden routers generally do not announce that they are hidden.
|
||||
Signed 3 40 or 72 43 or 75 Deprecated, unused. Payload contains a 40-byte DSA signature,
|
||||
HashCash 1 varies varies Experimental, unused. Payload contains an ASCII colon-separated hashcash string.
|
||||
Hidden 2 0 3 Experimental, unused. Hidden routers generally do not announce that they are hidden.
|
||||
Signed 3 40 or 72 43 or 75 Experimental, unused. Payload contains a 40-byte DSA signature,
|
||||
optionally followed by the 32-byte Hash of the signing Destination.
|
||||
Multiple 4 varies varies Deprecated, unused. Payload contains multiple certificates.
|
||||
Multiple 4 varies varies Experimental, unused. Payload contains multiple certificates.
|
||||
Key 5 4+ 7+ Since 0.9.12. See below for details.
|
||||
======== ========= ============== ============ =====
|
||||
|
||||
@ -433,57 +417,40 @@ Excess Signing Public Key Data 0+
|
||||
Excess Crypto Public Key Data 0+
|
||||
================================== ======
|
||||
|
||||
Warning: The key type order is the opposite of what you may expect;
|
||||
the Signing Public Key Type is first.
|
||||
|
||||
|
||||
The defined Signing Public Key types are:
|
||||
|
||||
====================== =========== ======================= ====== =====
|
||||
Type Type Code Total Public Key Length Since Usage
|
||||
====================== =========== ======================= ====== =====
|
||||
DSA_SHA1 0 128 0.9.12 Deprecated for Router Identities as of 0.9.58; discouraged for Destinations
|
||||
ECDSA_SHA256_P256 1 64 0.9.12 Deprecated Older Destinations
|
||||
ECDSA_SHA384_P384 2 96 0.9.12 Deprecated Rarely if ever used for Destinations
|
||||
ECDSA_SHA512_P521 3 132 0.9.12 Deprecated Rarely if ever used for Destinations
|
||||
RSA_SHA256_2048 4 256 0.9.12 Deprecated Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
RSA_SHA384_3072 5 384 0.9.12 Deprecated Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
DSA_SHA1 0 128 0.9.12 Legacy Router Identities and Destinations, never explicitly set
|
||||
ECDSA_SHA256_P256 1 64 0.9.12 Older Destinations
|
||||
ECDSA_SHA384_P384 2 96 0.9.12 Rarely if ever used for Destinations
|
||||
ECDSA_SHA512_P521 3 132 0.9.12 Rarely if ever used for Destinations
|
||||
RSA_SHA256_2048 4 256 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
RSA_SHA384_3072 5 384 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
RSA_SHA512_4096 6 512 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 7 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 8 32 0.9.25 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
reserved (GOST) 9 64 Reserved, see [Prop134]_
|
||||
reserved (GOST) 10 128 Reserved, see [Prop134]_
|
||||
reserved (GOST) 9 64 Reserved, see proposal 134
|
||||
reserved (GOST) 10 128 Reserved, see proposal 134
|
||||
RedDSA_SHA512_Ed25519 11 32 0.9.39 For Destinations and encrypted leasesets only; never used for Router Identities
|
||||
reserved (MLDSA) 12 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 13 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 14 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 15 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 16 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 17 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 18 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 19 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 20 Reserved, see [Prop169]_
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
====================== =========== ======================= ====== =====
|
||||
|
||||
The defined Crypto Public Key types are:
|
||||
|
||||
================ =========== ======================= ====== =====
|
||||
Type Type Code Total Public Key Length Since Usage
|
||||
================ =========== ======================= ====== =====
|
||||
ElGamal 0 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there
|
||||
P256 1 64 Reserved, see proposal 145
|
||||
P384 2 96 Reserved, see proposal 145
|
||||
P521 3 132 Reserved, see proposal 145
|
||||
X25519 4 32 0.9.38 See [ECIES]_ and proposal 156
|
||||
MLKEM512_X25519 5 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 6 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 7 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
reserved (NONE) 255 Reserved, see [Prop169]_
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
================ =========== ======================= ====== =====
|
||||
======== =========== ======================= =====
|
||||
Type Type Code Total Public Key Length Usage
|
||||
======== =========== ======================= =====
|
||||
ElGamal 0 256 All Router Identities and Destinations
|
||||
P256 1 64 Reserved, see proposal 145
|
||||
P384 2 96 Reserved, see proposal 145
|
||||
P521 3 132 Reserved, see proposal 145
|
||||
X25519 4 32 See [ECIES]_ and proposal 156
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
======== =========== ======================= =====
|
||||
|
||||
When a Key Certificate is not present, the preceeding 384 bytes in the
|
||||
Destination or RouterIdentity are defined as the 256-byte ElGamal PublicKey
|
||||
@ -531,11 +498,6 @@ Notes
|
||||
* Implementers are cautioned to prohibit excess data in Key Certificates.
|
||||
The appropriate length for each certificate type should be enforced.
|
||||
|
||||
* A KEY certificate with types 0,0 (ElGamal,DSA_SHA1) is allowed but discouraged.
|
||||
It is not well-tested and may cause issues in some implementations.
|
||||
Use a NULL certificate in the canonical representation of a
|
||||
(ElGamal,DSA_SHA1) Destination or RouterIdentity, which will be 4 bytes shorter
|
||||
than using a KEY certificate.
|
||||
|
||||
|
||||
.. _type-Mapping:
|
||||
@ -549,12 +511,7 @@ A set of key/value mappings or properties
|
||||
|
||||
Contents
|
||||
````````
|
||||
A 2-byte size Integer followed by a series of String=String; pairs.
|
||||
|
||||
WARNING: Most uses of Mapping are in signed structures, where the
|
||||
Mapping entries must be sorted by key, so the signature is immutable.
|
||||
Failure to sort by key will result in signature failures!
|
||||
|
||||
A 2-byte size Integer followed by a series of String=String; pairs
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -594,7 +551,7 @@ Notes
|
||||
* The encoding allows duplicate keys, however in any usage where the mapping is
|
||||
signed, duplicates may cause a signature failure.
|
||||
|
||||
* Mappings contained in I2NP messages (e.g. in a RouterAddress or RouterInfo)
|
||||
* Mappings contained in I2NP messages (i.e. in a RouterAddress or RouterInfo)
|
||||
must be sorted by key so that the signature will be invariant. Duplicate keys
|
||||
are not allowed.
|
||||
|
||||
@ -666,10 +623,11 @@ A PublicKey_ followed by a SigningPublicKey_ and then a Certificate_.
|
||||
|
||||
padding :: random data
|
||||
length -> 0 bytes or as specified in key certificate
|
||||
public_key length + padding length + signing_key length == 384 bytes
|
||||
padding length + signing_key length == 128 bytes
|
||||
|
||||
signing__key :: `SigningPublicKey` (partial or full)
|
||||
length -> 128 bytes or as specified in key certificate
|
||||
padding length + signing_key length == 128 bytes
|
||||
|
||||
certificate :: `Certificate`
|
||||
length -> >= 3 bytes
|
||||
@ -1180,13 +1138,6 @@ Notes
|
||||
* Maximum actual expires time is about 660 (11 minutes) for
|
||||
LeaseSet2_ and 65535 (the full 18.2 hours) for MetaLeaseSet_.
|
||||
|
||||
* LeaseSet_ (1) did not have a 'published' field, so versioning required
|
||||
a search for the earliest lease. LeaseSet2 adds a 'published' field
|
||||
with a resolution of one second. Routers should rate-limit sending
|
||||
new leasesets to floodfills to a rate much slower than once a second (per destination).
|
||||
If this is not implemented, then the code must ensure that each new leaseset
|
||||
has a 'published' time at least one second later than the one before, or else
|
||||
floodills will not store or flood the new leaseset.
|
||||
|
||||
|
||||
.. _struct-LeaseSet2:
|
||||
@ -1280,7 +1231,7 @@ by the Destination_'s SigningPrivateKey_ or the transient key.
|
||||
length -> 2 bytes
|
||||
|
||||
encryption_key :: `PublicKey`
|
||||
length -> keylen bytes
|
||||
length -> 256 bytes
|
||||
|
||||
num :: `Integer`
|
||||
length -> 1 byte
|
||||
@ -1297,77 +1248,6 @@ by the Destination_'s SigningPrivateKey_ or the transient key.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Encryption Key Preference
|
||||
`````````````````````````
|
||||
|
||||
For published (server) leasesets, the encryption keys are in order of server preference,
|
||||
most-preferred first. If clients support more than one encryption type, it is recommended
|
||||
that they honor the server preference and select the first supported type as the
|
||||
encryption method to use to connect to the server.
|
||||
Generally, the newer (higher-numbered) key types are more secure or efficient and
|
||||
are preferred, so the keys should be listed in reverse order of key type.
|
||||
|
||||
However, clients may, implementation-dependent, select based on their preference instead,
|
||||
or use some method to determine the "combined" preference. This may be useful as
|
||||
a configuration option, or for debugging.
|
||||
|
||||
The key order in unpublished (client) leasesets effectively does not matter, because
|
||||
connections will usually not be attempted to unpublished clients.
|
||||
Unless this order is used to determine a combined preference, as described above.
|
||||
|
||||
|
||||
Options
|
||||
```````
|
||||
As of API 0.9.66, a standard format for service record options
|
||||
is defined. See proposal 167 for details.
|
||||
Options other than service records, using a different format,
|
||||
may be defined in the future.
|
||||
|
||||
LS2 options MUST be sorted by key, so the signature is invariant.
|
||||
|
||||
Service record options are defined as follows:
|
||||
|
||||
- serviceoption := optionkey optionvalue
|
||||
- optionkey := _service._proto
|
||||
- service := The symbolic name of the desired service. Must be lower case. Example: "smtp".
|
||||
Allowed chars are [a-z0-9-] and must not start or end with a '-'.
|
||||
Standard identifiers from [REGISTRY]_ or Linux /etc/services must be used if defined there.
|
||||
- proto := The transport protocol of the desired service. Must be lower case, either "tcp" or "udp".
|
||||
"tcp" means streaming and "udp" means repliable datagrams.
|
||||
Protocol indicators for raw datagrams and datagram2 may be defined later.
|
||||
Allowed chars are [a-z0-9-] and must not start or end with a '-'.
|
||||
- optionvalue := self | srvrecord[,srvrecord]*
|
||||
- self := "0" ttl port [appoptions]
|
||||
- srvrecord := "1" ttl priority weight port target [appoptions]
|
||||
- ttl := time to live, integer seconds. Positive integer. Example: "86400".
|
||||
A minimum of 86400 (one day) is recommended, see Recommendations section below for details.
|
||||
- priority := The priority of the target host, lower value means more preferred. Non-negative integer. Example: "0"
|
||||
Only useful if more than one record, but required even if just one record.
|
||||
- weight := A relative weight for records with the same priority. Higher value means more chance of getting picked. Non-negative integer. Example: "0"
|
||||
Only useful if more than one record, but required even if just one record.
|
||||
- port := The I2CP port on which the service is to be found. Non-negative integer. Example: "25"
|
||||
Port 0 is supported but not recommended.
|
||||
- target := The hostname or b32 of the destination providing the service. A valid hostname as in [NAMING]_. Must be lower case.
|
||||
Example: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p" or "example.i2p".
|
||||
b32 is recommended unless the hostname is "well known", i.e. in official or default address books.
|
||||
- appoptions := arbitrary text specific to the application, must not contain " " or ",". Encoding is UTF-8.
|
||||
|
||||
Examples:
|
||||
|
||||
In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to one SMTP server:
|
||||
|
||||
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
|
||||
|
||||
In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to two SMTP servers:
|
||||
|
||||
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p,86400 1 0 25 cccccccccccccccccccccccccccccccccccccccccccc.b32.i2p"
|
||||
|
||||
In LS2 for bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p, pointing to itself as a SMTP server:
|
||||
|
||||
"_smtp._tcp" "0 999999 25"
|
||||
|
||||
|
||||
Notes
|
||||
`````
|
||||
* The public key of the destination was used for the old I2CP-to-I2CP
|
||||
@ -1390,10 +1270,6 @@ Notes
|
||||
* The key length is provided for each key, so that floodfills and clients
|
||||
may parse the structure even if not all encryption types are known or supported.
|
||||
|
||||
* See note on the 'published' field in LeaseSet2Header_
|
||||
|
||||
* The options mapping, if the size is greater than one, must be sorted by key, so the signature is invariant.
|
||||
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/LeaseSet2.html
|
||||
|
||||
@ -1575,8 +1451,6 @@ Notes
|
||||
destination, or the transient signing public key, if an offline signature
|
||||
is included in the leaseset2 header.
|
||||
|
||||
* See note on the 'published' field in LeaseSet2Header_
|
||||
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/MetaLeaseSet.html
|
||||
|
||||
@ -1701,10 +1575,6 @@ Notes
|
||||
* See proposal 123 for notes on using offline signatures
|
||||
with encrypted leasesets.
|
||||
|
||||
* See note on the 'published' field in LeaseSet2Header_
|
||||
(same issue, even though we do not use the LeaseSet2Header format here)
|
||||
|
||||
|
||||
.. _EncryptedLeaseSet: {{ site_url('docs/spec/encryptedleaseset') }}
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/EncryptedLeaseSet.html
|
||||
@ -1909,9 +1779,6 @@ References
|
||||
.. [ECIES]
|
||||
{{ spec_url('ecies') }}
|
||||
|
||||
.. [ECIES-HYBRID]
|
||||
{{ spec_url('ecies-hybrid') }}
|
||||
|
||||
.. [ECIES-ROUTERS]
|
||||
{{ spec_url('ecies-routers') }}
|
||||
|
||||
@ -1930,21 +1797,9 @@ References
|
||||
.. [I2NP]
|
||||
{{ site_url('docs/protocol/i2np', True) }}
|
||||
|
||||
.. [NAMING]
|
||||
{{ site_url('docs/naming', True) }}
|
||||
|
||||
.. [NETDB-ROUTERINFO]
|
||||
{{ site_url('docs/how/network-database', True) }}#routerInfo
|
||||
|
||||
.. [Prop134]
|
||||
{{ proposal_url('134') }}
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
||||
|
||||
.. [REGISTRY]
|
||||
http://www.dns-sd.org/ServiceTypes.html
|
||||
|
||||
.. [SSU]
|
||||
{{ site_url('docs/transport/ssu', True) }}
|
||||
|
||||
|
@ -3,8 +3,8 @@ Low-level Cryptography Specification
|
||||
====================================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2020-09
|
||||
:accuratefor: 0.9.47
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -12,18 +12,6 @@ Low-level Cryptography Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
NOTE: MOSTLY OBSOLETE -
|
||||
See the following documents for current specifications:
|
||||
|
||||
- {{ spec_url('ecies') }}
|
||||
- {{ spec_url('encryptedleaseset') }}
|
||||
- {{ spec_url('ntcp2') }}
|
||||
- {{ spec_url('red25519') }}
|
||||
- {{ spec_url('ssu2') }}
|
||||
- {{ spec_url('tunnel-creation-ecies') }}
|
||||
|
||||
|
||||
|
||||
This page specifies the low-level details of the cryptography in I2P.
|
||||
|
||||
There are several cryptographic algorithms in use within I2P.
|
||||
@ -51,10 +39,11 @@ of ElGamal asymmetric encryption and AES symmetric encryption.
|
||||
Newer protocols NTCP2 and ECIES-X25519-AEAD-Ratchet
|
||||
use a combination of X25519 key exchange and ChaCha20/Poly1305 symmetric encryption.
|
||||
|
||||
- ECIES-X25519-AEAD-Ratchet has replaced ElGamal/AES+SessionTags.
|
||||
- NTCP2 has replaced NTCP.
|
||||
- SSU2 has replaced SSU.
|
||||
- X25519 tunnel creation has replaced ElGamal tunnel creation.
|
||||
- ECIES-X25519-AEAD-Ratchet design and implementation are complete,
|
||||
and will replace ElGamal/AES+SessionTags in late 2020.
|
||||
- SSU2, using X25519 and ChaCha20/Poly1305, is scheduled for design in late 2020
|
||||
to replace SSU in 2021.
|
||||
|
||||
|
||||
Asymmetric Encryption
|
||||
|
@ -3,8 +3,8 @@ Datagram Specification
|
||||
======================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: February 2019
|
||||
:accuratefor: 0.9.39
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -14,139 +14,11 @@ Overview
|
||||
|
||||
See [DATAGRAMS]_ for an overview of the Datagrams API.
|
||||
|
||||
The following types are defined. The standard protocol numbers
|
||||
are listed, however any other protocol numbers may be used other than
|
||||
the streaming protocol number (6), application-specific.
|
||||
|
||||
|
||||
========= ======== ========== ============== ================== =====
|
||||
Type Protocol Repliable? Authenticated? Replay Prevention? As Of
|
||||
========= ======== ========== ============== ================== =====
|
||||
Raw 18 no no no
|
||||
Datagram1 17 yes yes no
|
||||
Datagram2 19 yes yes yes 0.9.66
|
||||
Datagram3 20 yes no no 0.9.66
|
||||
========= ======== ========== ============== ================== =====
|
||||
|
||||
|
||||
Support for Datagram2 and Datagram3 in various router and library implementations
|
||||
is TBD. Check the documentation for those implementations.
|
||||
|
||||
|
||||
|
||||
Datagram Type Identification
|
||||
----------------------------
|
||||
|
||||
The four datagram types do not share a common header with the protocol
|
||||
version in the same place. Packets cannot be identified by type
|
||||
based on their content. When using multiple types on the same session,
|
||||
or a single type together with streaming, applications must use
|
||||
protocol numbers and/or I2CP/SAM ports to route incoming packets to the
|
||||
right place. Using standard protocol numbers will make this easier.
|
||||
Leaving the protocol number unset (0 or PROTO_ANY), even for a datagram-only
|
||||
application, is not recommended as it increases the chance of routing
|
||||
errors and makes upgrades to a multi-protocol application harder.
|
||||
Version fields in Datagram 2 and 3 are provided only as
|
||||
an additional check for routing errors and future changes.
|
||||
|
||||
|
||||
|
||||
Application Design
|
||||
------------------
|
||||
|
||||
All uses of datagrams are application-specific.
|
||||
|
||||
As authenticated datagrams carry substantial overhead,
|
||||
a typical application uses both authenticated and non-authenticated datagrams.
|
||||
A typical design is to send single authenticated datagram
|
||||
containing a token from the client to the server.
|
||||
The server replies with an unauthenticated datagram containing the same token.
|
||||
Any subsequent communication, before token timeout, uses raw datagrams.
|
||||
|
||||
Applications send and receive datagrams using protocol and port numbers
|
||||
via the I2CP API [I2CP]_ or SAMv3 [SAMv3]_.
|
||||
|
||||
Datagrams are, of course, unreliable. Applications must design for unreliable
|
||||
delivery. Within I2P, delivery is reliable hop-to-hop
|
||||
if the next hop is reachable, as the NTCP2 and SSU2
|
||||
transports provide reliablity. However, end-to-end delivery is
|
||||
not reliable, as I2NP messages may be dropped within any hop due
|
||||
to queue limits, expirations, timeouts, bandwidth limits,
|
||||
or unreachable next-hops.
|
||||
|
||||
|
||||
Datagram Size
|
||||
-------------
|
||||
|
||||
The nominal size limit for I2NP messages, including datagrams, is 64 KB.
|
||||
Garlic and tunnel message overhead reduce somewhat.
|
||||
|
||||
However, all I2NP messages must be fragmented into 1 KB tunnel messages.
|
||||
The drop probability of a n KB I2NP message is the exponential function of
|
||||
the drop probability of a single tunnel message, p ** n.
|
||||
As fragmentation results in a burst of tunnel messages,
|
||||
actual drop probability is much higher than the exponential
|
||||
function would imply, due to queue limits and active queue management
|
||||
(AQM, CoDel or similar) in router implementations.
|
||||
|
||||
Recommended typical max size to ensure reliable delivery is a few KB,
|
||||
or at the most 10 KB.
|
||||
With careful analysis of overhead sizes at all protocol layers (except transport),
|
||||
developers should set a max payload size
|
||||
that will fit precisely in one, two, or three tunnel messages.
|
||||
This will maximize efficiency and reliability.
|
||||
Overhead at various layers includes the gzip header,
|
||||
I2NP header, garlic message header, garlic encryption,
|
||||
tunnel message header, tunnel message fragmentation headers,
|
||||
and others.
|
||||
See streaming MTU calculations in Proposal 144 [Prop144]_
|
||||
and ConnectionOptions.java in the Java I2P source for examples.
|
||||
|
||||
|
||||
|
||||
SAM Considerations
|
||||
------------------
|
||||
|
||||
Applications send and receive datagrams using protocol and port numbers
|
||||
via the I2CP API or SAM. Specifying protocol and port numbers
|
||||
via SAM requires SAM v3.2 or higher.
|
||||
Using both datagrams and streaming (UDP and TCP) on the same SAM session (tunnels)
|
||||
requires SAM v3.3 or higher.
|
||||
Using multiple datagram types on the same SAM session (tunnels)
|
||||
requires SAM v3.3 or higher.
|
||||
SAM v3.3 is only supported by the Java I2P router at this time.
|
||||
|
||||
SAM support for Datagram2 and Datagram3 in various router and library implementations
|
||||
is TBD. Check the documentation for those implementations.
|
||||
|
||||
Note that sizes over a typical 1500 byte network MTU will prohibit
|
||||
SAM applications from transporting unfragmented packets to/from
|
||||
the SAM server, if the application and server are on separate computers.
|
||||
Typically, this is not the case, they are both on localhost,
|
||||
where the MTU is 65536 or higher.
|
||||
If a SAM application is expected to be separated on a different
|
||||
computer from the server, max payload for a repliable datagram is
|
||||
slightly under 1 KB.
|
||||
|
||||
|
||||
|
||||
PQ Considerations
|
||||
-----------------
|
||||
|
||||
If the MLDSA portion of the Post-Quantum proposal [Prop169]_ is implemented,
|
||||
overhead will increase substantially.
|
||||
The size of a destination + signature will increase from 391 + 64 = 455 bytes
|
||||
to a minimum of 3739 for MLDSA44 and a maximum of 7226 for MLDSA87.
|
||||
The practical effects of this are to be determined.
|
||||
Datagram3, with authentication provided by the router, may be a solution.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _raw:
|
||||
|
||||
Raw (Non-Repliable) Datagrams
|
||||
=============================
|
||||
Non-Repliable Datagrams
|
||||
=======================
|
||||
|
||||
Non-repliable datagrams have no 'from' address and are not authenticated. They
|
||||
are also called "raw" datagrams. Strictly speaking, they are not "datagrams"
|
||||
@ -155,10 +27,6 @@ However, SAM and the I2PTunnel classes support "raw datagrams".
|
||||
|
||||
The standard I2CP protocol number for raw datagrams is PROTO_DATAGRAM_RAW (18).
|
||||
|
||||
The format is not specified here, it is defined by the application.
|
||||
For completeness, we include a picture of the format below.
|
||||
|
||||
|
||||
Format
|
||||
------
|
||||
|
||||
@ -169,22 +37,22 @@ Format
|
||||
| payload...
|
||||
+----+----+----+----+----//
|
||||
|
||||
length: 0 - about 64 KB (see notes)
|
||||
length: 0 - unlimited (see notes)
|
||||
{% endhighlight %}
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
The practical length is limited by both overhead at various layers and reliability.
|
||||
|
||||
|
||||
|
||||
The practical length is limited by lower layers of protocols - the tunnel
|
||||
message spec [TUNMSG]_ limits messages to about 61.2 KB and the transports
|
||||
[TRANSPORT]_ currently limit messages to about 32 KB, although this may be
|
||||
raised in the future.
|
||||
|
||||
|
||||
.. _repliable:
|
||||
|
||||
Datagram1 (Repliable)
|
||||
=====================
|
||||
Repliable Datagrams
|
||||
===================
|
||||
|
||||
Repliable datagrams contain a 'from' address and a signature. These add at
|
||||
least 427 bytes of overhead.
|
||||
@ -236,7 +104,7 @@ Format
|
||||
The signature may be verified by the signing public key of $from
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 63 KB (see notes)
|
||||
Length: 0 to ~31.5 KB (see notes)
|
||||
|
||||
Total length: Payload length + 427+
|
||||
{% endhighlight %}
|
||||
@ -244,7 +112,9 @@ Format
|
||||
Notes
|
||||
-----
|
||||
|
||||
* The practical length is limited by both overhead at various layers and reliability.
|
||||
* The practical length is limited by lower layers of protocols - the transports
|
||||
[TRANSPORT]_ currently limit messages to about 32 KB, so the data length here
|
||||
is limited to about 31.5 KB.
|
||||
|
||||
* See important notes about the reliability of large datagrams [DATAGRAMS]_. For
|
||||
best results, limit the payload to about 10 KB or less.
|
||||
@ -255,241 +125,12 @@ Notes
|
||||
for LS2 (proposal 123). A new protocol with flags must be defined for that.
|
||||
|
||||
|
||||
|
||||
.. _datagram2:
|
||||
|
||||
Datagram2
|
||||
=========
|
||||
|
||||
The Datagram2 format is as specified in Proposal 163 [Prop163]_.
|
||||
The I2CP protocol number for Datagram2 is 19.
|
||||
|
||||
Datagram2 is intended as a replacement for Datagram1.
|
||||
It adds the following features to Datagram1:
|
||||
|
||||
- Replay prevention
|
||||
- Offline signature support
|
||||
- Flags and options fields for extensibility
|
||||
|
||||
Note that the signature calculation algorithm for Datagram2
|
||||
is substantially different than for Datagram1.
|
||||
|
||||
|
||||
Format
|
||||
------
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' -%}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ from ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| flags | options (optional) |
|
||||
+----+----+ +
|
||||
~ ~
|
||||
~ ~
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ offline_signature (optional) ~
|
||||
~ expires, sigtype, pubkey, offsig ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ payload ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ signature ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
from :: a `Destination`
|
||||
length: 387+ bytes
|
||||
The originator and (unless offline signed) signer of the datagram
|
||||
|
||||
flags :: (2 bytes)
|
||||
Bit order: 15 14 ... 3 2 1 0
|
||||
Bits 3-0: Version: 0x02 (0 0 1 0)
|
||||
Bit 4: If 0, no options; if 1, options mapping is included
|
||||
Bit 5: If 0, no offline sig; if 1, offline signed
|
||||
Bits 15-6: unused, set to 0 for compatibility with future uses
|
||||
|
||||
options :: (2+ bytes if present)
|
||||
If flag indicates options are present, a `Mapping`
|
||||
containing arbitrary text options
|
||||
|
||||
offline_signature ::
|
||||
If flag indicates offline keys, the offline signature section,
|
||||
as specified in the Common Structures Specification,
|
||||
with the following 4 fields. Length: varies by online and offline
|
||||
sig types, typically 102 bytes for Ed25519
|
||||
This section can, and should, be generated offline.
|
||||
|
||||
expires :: Expires timestamp
|
||||
(4 bytes, big endian, seconds since epoch, rolls over in 2106)
|
||||
|
||||
sigtype :: Transient sig type (2 bytes, big endian)
|
||||
|
||||
pubkey :: Transient signing public key (length as implied by sig type),
|
||||
typically 32 bytes for Ed25519 sig type.
|
||||
|
||||
offsig :: a `Signature`
|
||||
Signature of expires timestamp, transient sig type,
|
||||
and public key, by the destination public key,
|
||||
length: 40+ bytes, as implied by the Signature type, typically
|
||||
64 bytes for Ed25519 sig type.
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 61 KB (see notes)
|
||||
|
||||
signature :: a `Signature`
|
||||
Signature type must match the signing public key type of $from
|
||||
(if no offline signature) or the transient sigtype
|
||||
(if offline signed)
|
||||
length: 40+ bytes, as implied by the Signature type, typically
|
||||
64 bytes for Ed25519 sig type.
|
||||
The `Signature` of the payload and other fields as specified below.
|
||||
The signature is verified by the signing public key of $from
|
||||
(if no offline signature) or the transient pubkey
|
||||
(if offline signed)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Total length: minimum 433 + payload length;
|
||||
typical length for X25519 senders and without offline signatures:
|
||||
457 + payload length.
|
||||
Note that the message will typically be compressed with gzip at the I2CP layer,
|
||||
which will result in significant savings if the from destination is compressible.
|
||||
|
||||
Note: The offline signature format is the same as in the Common Structures spec [Common]_ and [Streaming]_.
|
||||
|
||||
Signatures
|
||||
----------
|
||||
|
||||
The signature is over the following fields.
|
||||
|
||||
- Prelude: The 32-byte hash of the target destination (not included in the datagram)
|
||||
- flags
|
||||
- options (if present)
|
||||
- offline_signature (if present)
|
||||
- payload
|
||||
|
||||
In repliable datagram, for the DSA_SHA1 key type, the signature was over the
|
||||
SHA-256 hash of the payload, not the payload itself; here, the signature is
|
||||
always over the fields above (NOT the hash), regardless of key type.
|
||||
|
||||
|
||||
ToHash Verification
|
||||
-------------------
|
||||
|
||||
Receivers must verify the signature (using their destination hash)
|
||||
and discard the datagram on failure, for replay prevention.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _datagram3:
|
||||
|
||||
Datagram3
|
||||
=========
|
||||
|
||||
The Datagram3 format is as specified in Proposal 163 [Prop163]_.
|
||||
The I2CP protocol number for Datagram3 is 20.
|
||||
|
||||
Datagram3 is intended as an enhanced version of raw datagrams.
|
||||
It adds the following features to raw datagrams:
|
||||
|
||||
- Repliability
|
||||
- Flags and options fields for extensibility
|
||||
|
||||
Datagram3 is NOT authenticated.
|
||||
In a future proposal, authentication may be provided by
|
||||
the router's ratchet layer, and authentication status
|
||||
would be passed to the client.
|
||||
|
||||
|
||||
|
||||
Format
|
||||
------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' -%}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ fromhash ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| flags | options (optional) |
|
||||
+----+----+ +
|
||||
~ ~
|
||||
~ ~
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ payload ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
fromhash :: a `Hash`
|
||||
length: 32 bytes
|
||||
The originator of the datagram
|
||||
|
||||
flags :: (2 bytes)
|
||||
Bit order: 15 14 ... 3 2 1 0
|
||||
Bits 3-0: Version: 0x03 (0 0 1 1)
|
||||
Bit 4: If 0, no options; if 1, options mapping is included
|
||||
Bits 15-5: unused, set to 0 for compatibility with future uses
|
||||
|
||||
options :: (2+ bytes if present)
|
||||
If flag indicates options are present, a `Mapping`
|
||||
containing arbitrary text options
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 61 KB (see notes)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Total length: minimum 34 + payload length.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [Common]
|
||||
{{ spec_url('common-structures') }}
|
||||
|
||||
.. [DATAGRAMS]
|
||||
{{ site_url('docs/api/datagrams', True) }}
|
||||
|
||||
.. [I2CP]
|
||||
{{ site_url('docs/protocol/i2cp', True) }}
|
||||
|
||||
.. [Prop144]
|
||||
{{ proposal_url('144') }}
|
||||
|
||||
.. [Prop163]
|
||||
{{ proposal_url('163') }}
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('163') }}
|
||||
|
||||
.. [SAMv3]
|
||||
{{ site_url('docs/api/samv3') }}
|
||||
|
||||
.. [Streaming]
|
||||
{{ spec_url('streaming') }}
|
||||
|
||||
.. [TRANSPORT]
|
||||
{{ site_url('docs/transport', True) }}
|
||||
|
||||
|
@ -1,833 +0,0 @@
|
||||
===================================
|
||||
PQ Hybrid ECIES-X25519-AEAD-Ratchet
|
||||
===================================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Note
|
||||
====
|
||||
|
||||
Implementation, testing, and rollout in progress in the various
|
||||
router implementations. Check the documentation of those implementations for status.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This is the PQ Hybrid variant of the ECIES-X25519-AEAD-Ratchet protocol [ECIES]_.
|
||||
It is the first phase of the overall PQ proposal [Prop169]_
|
||||
to be approved. See that proposal for overall goals, threat models,
|
||||
analysis, alternatives, and additional information.
|
||||
|
||||
This specification contains only the differences from standard [ECIES]_
|
||||
and must be read in conjunction with that specification.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
We use the NIST FIPS 203 standard [FIPS203]_
|
||||
which is based on, but not compatible with,
|
||||
CRYSTALS-Kyber (versions 3.1, 3, and older).
|
||||
|
||||
Hybrid handshakes are as specified in [Noise-Hybrid]_.
|
||||
|
||||
|
||||
Key Exchange
|
||||
-------------
|
||||
|
||||
We define a hybrid key exchange for Ratchet.
|
||||
PQ KEM provides ephemeral keys only, and does not directly support
|
||||
static-key handshakes such as Noise IK.
|
||||
|
||||
We define the three ML-KEM variants as in [FIPS203]_,
|
||||
for 3 new encryption types total.
|
||||
Hybrid types are only defined in combination with X25519.
|
||||
|
||||
The new encryption types are:
|
||||
|
||||
================ ====
|
||||
Type Code
|
||||
================ ====
|
||||
MLKEM512_X25519 5
|
||||
MLKEM768_X25519 6
|
||||
MLKEM1024_X25519 7
|
||||
================ ====
|
||||
|
||||
Overhead will be substantial. Typical message 1 and 2 sizes (for IK)
|
||||
are currently around 100 bytes (before any additional payload).
|
||||
This will increase by 8x to 15x depending on algorithm.
|
||||
|
||||
|
||||
New Crypto Required
|
||||
-------------------
|
||||
|
||||
- ML-KEM (formerly CRYSTALS-Kyber) [FIPS203]_
|
||||
- SHA3-128 (formerly Keccak-256) [FIPS202]_ Used only for SHAKE128
|
||||
- SHA3-256 (formerly Keccak-512) [FIPS202]_
|
||||
- SHAKE128 and SHAKE256 (XOF extensions to SHA3-128 and SHA3-256) [FIPS202]_
|
||||
|
||||
Test vectors for SHA3-256, SHAKE128, and SHAKE256 are at [NIST-VECTORS]_.
|
||||
|
||||
Note that the Java bouncycastle library supports all the above.
|
||||
C++ library support is in OpenSSL 3.5 [OPENSSL]_.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Common Structures
|
||||
-----------------
|
||||
|
||||
See the common structures specification [COMMON]_ for key lengths and identifiers.
|
||||
|
||||
|
||||
|
||||
Handshake Patterns
|
||||
------------------
|
||||
|
||||
Handshakes use [Noise]_ handshake patterns.
|
||||
|
||||
The following letter mapping is used:
|
||||
|
||||
- e = one-time ephemeral key
|
||||
- s = static key
|
||||
- p = message payload
|
||||
- e1 = one-time ephemeral PQ key, sent from Alice to Bob
|
||||
- ekem1 = the KEM ciphertext, sent from Bob to Alice
|
||||
|
||||
The following modifications to XK and IK for hybrid forward secrecy (hfs) are
|
||||
as specified in [Noise-Hybrid]_ section 5:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
IK: IKhfs:
|
||||
<- s <- s
|
||||
... ...
|
||||
-> e, es, s, ss, p -> e, es, e1, s, ss, p
|
||||
<- tag, e, ee, se, p <- tag, e, ee, ekem1, se, p
|
||||
<- p <- p
|
||||
p -> p ->
|
||||
|
||||
e1 and ekem1 are encrypted. See pattern definitions below.
|
||||
NOTE: e1 and ekem1 are different sizes (unlike X25519)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
The e1 pattern is defined as follows, as specified in [Noise-Hybrid]_ section 4:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
For Alice:
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// EncryptAndHash(encap_key)
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
n++
|
||||
MixHash(ciphertext)
|
||||
|
||||
For Bob:
|
||||
|
||||
// DecryptAndHash(ciphertext)
|
||||
encap_key = DECRYPT(k, n, ciphertext, ad)
|
||||
n++
|
||||
MixHash(ciphertext)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
The ekem1 pattern is defined as follows, as specified in [Noise-Hybrid]_ section 4:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
For Bob:
|
||||
|
||||
(kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// EncryptAndHash(kem_ciphertext)
|
||||
ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
// MixKey
|
||||
MixKey(kem_shared_key)
|
||||
|
||||
|
||||
For Alice:
|
||||
|
||||
// DecryptAndHash(ciphertext)
|
||||
kem_ciphertext = DECRYPT(k, n, ciphertext, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
// MixKey
|
||||
kem_shared_key = DECAPS(kem_ciphertext, decap_key)
|
||||
MixKey(kem_shared_key)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
Defined ML-KEM Operations
|
||||
-------------------------
|
||||
|
||||
We define the following functions corresponding to the cryptographic building blocks used
|
||||
as defined in [FIPS203]_.
|
||||
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
Alice creates the encapsulation and decapsulation keys
|
||||
The encapsulation key is sent in the NS message.
|
||||
encap_key and decap_key sizes vary based on ML-KEM variant.
|
||||
|
||||
(ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
Bob calculates the ciphertext and shared key,
|
||||
using the ciphertext received in the NS message.
|
||||
The ciphertext is sent in the NSR message.
|
||||
ciphertext size varies based on ML-KEM variant.
|
||||
The kem_shared_key is always 32 bytes.
|
||||
|
||||
kem_shared_key = DECAPS(ciphertext, decap_key)
|
||||
Alice calculates the shared key,
|
||||
using the ciphertext received in the NSR message.
|
||||
The kem_shared_key is always 32 bytes.
|
||||
|
||||
Note that both the encap_key and the ciphertext are encrypted inside ChaCha/Poly
|
||||
blocks in the Noise handshake messages 1 and 2.
|
||||
They will be decrypted as part of the handshake process.
|
||||
|
||||
The kem_shared_key is mixed into the chaining key with MixHash().
|
||||
See below for details.
|
||||
|
||||
|
||||
|
||||
Noise Handshake KDF
|
||||
---------------------
|
||||
|
||||
|
||||
Overview
|
||||
````````
|
||||
|
||||
The hybrid handshake is defined in [Noise-Hybrid]_.
|
||||
The first message, from Alice to Bob, contains e1, the encapsulation key, before the message payload.
|
||||
This is treated as an additional static key; call EncryptAndHash() on it (as Alice)
|
||||
or DecryptAndHash() (as Bob).
|
||||
Then process the message payload as usual.
|
||||
|
||||
The second message, from Bob to Alice, contains ekem1, the ciphertext, before the message payload.
|
||||
This is treated as an additional static key; call EncryptAndHash() on it (as Bob)
|
||||
or DecryptAndHash() (as Alice).
|
||||
Then, calculate the kem_shared_key and call MixKey(kem_shared_key).
|
||||
Then process the message payload as usual.
|
||||
|
||||
|
||||
|
||||
Noise identifiers
|
||||
`````````````````
|
||||
|
||||
These are the Noise initialization strings:
|
||||
|
||||
- "Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256"
|
||||
- "Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256"
|
||||
- "Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256"
|
||||
|
||||
|
||||
|
||||
Alice KDF for NS Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'es' message pattern and before the 's' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// EncryptAndHash(encap_key)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
n++
|
||||
|
||||
// MixHash(ciphertext)
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
NOTE: For the next section (payload for XK or static key for IK),
|
||||
the keydata and chain key remain the same,
|
||||
and n now equals 1 (instead of 0 for non-hybrid).
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Bob KDF for NS Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'es' message pattern and before the 's' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
|
||||
// DecryptAndHash(encap_key_section)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
encap_key = DECRYPT(k, n, encap_key_section, ad)
|
||||
n++
|
||||
|
||||
// MixHash(encap_key_section)
|
||||
h = SHA256(h || encap_key_section)
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
NOTE: For the next section (payload for XK or static key for IK),
|
||||
the keydata and chain key remain the same,
|
||||
and n now equals 1 (instead of 0 for non-hybrid).
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Bob KDF for NSR Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'ee' message pattern and before the 'se' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
(kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// EncryptAndHash(kem_ciphertext)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
|
||||
|
||||
// MixHash(ciphertext)
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
End of "ekem1" message pattern.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Alice KDF for NSR Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'ee' message pattern and before the 'ss' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
// DecryptAndHash(kem_ciphertext_section)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
kem_ciphertext = DECRYPT(k, n, kem_ciphertext_section, ad)
|
||||
|
||||
// MixHash(kem_ciphertext_section)
|
||||
h = SHA256(h || kem_ciphertext_section)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
kem_shared_key = DECAPS(kem_ciphertext, decap_key)
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
End of "ekem1" message pattern.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
KDF for split()
|
||||
```````````````
|
||||
unchanged
|
||||
|
||||
|
||||
Message Format
|
||||
--------------
|
||||
|
||||
NS Format
|
||||
`````````
|
||||
|
||||
Changes: Current ratchet contained the static key in the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ public key.
|
||||
The second section contains the static key.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| New Session Ephemeral Public Key |
|
||||
+ 32 bytes +
|
||||
| Encoded with Elligator2 |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for encap_key Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ 32 bytes +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Static Key Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| ChaCha20 encrypted data |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Payload Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Decrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
Payload Part 1:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key +
|
||||
| |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
| |
|
||||
+ (32 bytes) +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Sizes:
|
||||
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
Type Type Code X len NS len NS Enc len NS Dec len PQ key len pl len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 96+pl 64+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 912+pl 880+pl 800+pl 800 pl
|
||||
MLKEM768_X25519 6 32 1296+pl 1360+pl 1184+pl 1184 pl
|
||||
MLKEM1024_X25519 7 32 1680+pl 1648+pl 1568+pl 1568 pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note that the payload must contain a DateTime block, so the minimum payload size is 7.
|
||||
The minimum NS sizes may be calculated accordingly.
|
||||
|
||||
|
||||
|
||||
NSR Format
|
||||
``````````
|
||||
|
||||
Changes: Current ratchet has an empty payload for the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ ciphertext.
|
||||
The second section has an empty payload.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Session Tag 8 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Ephemeral Public Key +
|
||||
| |
|
||||
+ 32 bytes +
|
||||
| Encoded with Elligator2 |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| ChaCha20 encrypted ML-KEM ciphertext |
|
||||
+ (see table below for length) +
|
||||
~ ~
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for ciphertext Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for key Section (no data) +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| ChaCha20 encrypted data |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Payload Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Decrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
Payload Part 1:
|
||||
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM ciphertext +
|
||||
| |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
empty
|
||||
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Sizes:
|
||||
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
Type Type Code Y len NSR len NSR Enc len NSR Dec len PQ CT len opt len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 72+pl 32+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 856+pl 816+pl 768+pl 768 pl
|
||||
MLKEM768_X25519 6 32 1176+pl 1136+pl 1088+pl 1088 pl
|
||||
MLKEM1024_X25519 7 32 1656+pl 1616+pl 1568+pl 1568 pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note that while NSR will normally have a nonzero payload,
|
||||
the ratchet specification [ECIES]_ does not require it, so the minimum payload size is 0.
|
||||
The minimum NSR sizes may be caculated accordingly.
|
||||
|
||||
|
||||
|
||||
Overhead Analysis
|
||||
=================
|
||||
|
||||
Key Exchange
|
||||
-------------
|
||||
|
||||
Size increase (bytes):
|
||||
|
||||
================ ============== =============
|
||||
Type Pubkey (NS) Cipertext (NSR)
|
||||
================ ============== =============
|
||||
MLKEM512_X25519 +816 +784
|
||||
MLKEM768_X25519 +1200 +1104
|
||||
MLKEM1024_X25519 +1584 +1584
|
||||
================ ============== =============
|
||||
|
||||
Speed:
|
||||
|
||||
Speeds as reported by [CLOUDFLARE]_:
|
||||
|
||||
================ ==============
|
||||
Type Relative speed
|
||||
================ ==============
|
||||
X25519 DH/keygen baseline
|
||||
MLKEM512 2.25x faster
|
||||
MLKEM768 1.5x faster
|
||||
MLKEM1024 1x (same)
|
||||
XK 4x DH (keygen + 3 DH)
|
||||
MLKEM512_X25519 4x DH + 2x PQ (keygen + enc/dec) = 4.9x DH = 22% slower
|
||||
MLKEM768_X25519 4x DH + 2x PQ (keygen + enc/dec) = 5.3x DH = 32% slower
|
||||
MLKEM1024_X25519 4x DH + 2x PQ (keygen + enc/dec) = 6x DH = 50% slower
|
||||
================ ==============
|
||||
|
||||
|
||||
Security Analysis
|
||||
=================
|
||||
|
||||
NIST security categories are summarized in [NIST-PQ-END]_ slide 10.
|
||||
Preliminary criteria:
|
||||
Our minimum NIST security category should be 2 for hybrid protocols
|
||||
and 3 for PQ-only.
|
||||
|
||||
======== ======
|
||||
Category As Secure As
|
||||
======== ======
|
||||
1 AES128
|
||||
2 SHA256
|
||||
3 AES192
|
||||
4 SHA384
|
||||
5 AES256
|
||||
======== ======
|
||||
|
||||
|
||||
Handshakes
|
||||
----------
|
||||
These are all hybrid protocols.
|
||||
Probably need to prefer MLKEM768; MLKEM512 is not secure enough.
|
||||
|
||||
NIST security categories [FIPS203]_ :
|
||||
|
||||
========= ========
|
||||
Algorithm Security Category
|
||||
========= ========
|
||||
MLKEM512 1
|
||||
MLKEM768 3
|
||||
MLKEM1024 5
|
||||
========= ========
|
||||
|
||||
|
||||
Type Preferences
|
||||
=================
|
||||
|
||||
|
||||
The recommended type for initial support, based on security category and key length, is:
|
||||
|
||||
MLKEM768_X25519 (type 6)
|
||||
|
||||
|
||||
|
||||
Implementation Notes
|
||||
=====================
|
||||
|
||||
Library Support
|
||||
---------------
|
||||
|
||||
Bouncycastle, BoringSSL, and WolfSSL libraries support MLKEM now.
|
||||
OpenSSL support is be in their 3.5 release April 8, 2025 [OPENSSL]_.
|
||||
|
||||
|
||||
Shared Tunnels
|
||||
--------------
|
||||
|
||||
Auto-classify/detect of multiple protocols on the same tunnels should be possible based
|
||||
on a length check of message 1 (New Session Message).
|
||||
Using MLKEM512_X25519 as an example, message 1 length is 816 bytes larger
|
||||
than current ratchet protocol, and the minimum message 1 size (with only a DateTime payload included)
|
||||
is 919 bytes. Most message 1 sizes with current ratchet have a payload less than
|
||||
816 bytes, so they can be classified as non-hybrid ratchet.
|
||||
Large messages are probably POSTs which are rare.
|
||||
|
||||
So the recommended strategy is:
|
||||
|
||||
- If message 1 is less than 919 bytes, it's the current ratchet protocol.
|
||||
- If message 1 is greater than or equal to 919 bytes, it's probably MLKEM512_X25519.
|
||||
Try MLKEM512_X25519 first, and if it fails, try the current ratchet protocol.
|
||||
|
||||
This should allow us to efficiently support standard ratchet and hybrid ratchet
|
||||
on the same destination, just as we previously supported ElGamal and ratchet
|
||||
on the same destination. Therefore, we can migrate to the MLKEM hybrid protocol
|
||||
much more quickly than if we could not support dual-protocols for the same destination,
|
||||
because we can add MLKEM support to existing destinations.
|
||||
|
||||
The required supported combinations are:
|
||||
|
||||
- X25519 + MLKEM512
|
||||
- X25519 + MLKEM768
|
||||
- X25519 + MLKEM1024
|
||||
|
||||
The following combinations may be complex, and are NOT required to be supported,
|
||||
but may be, implementation-dependent:
|
||||
|
||||
- More than one MLKEM
|
||||
- ElG + one or more MLKEM
|
||||
- X25519 + one or more MLKEM
|
||||
- ElG + X25519 + one or more MLKEM
|
||||
|
||||
It is not required to support multiple MLKEM algorithms
|
||||
(for example, MLKEM512_X25519 and MLKEM_768_X25519)
|
||||
on the same destination. Pick just one.
|
||||
Implementation-dependent.
|
||||
|
||||
It is not required to support three algorithms (for example X25519, MLKEM512_X25519, and MLKEM769_X25519)
|
||||
on the same destination. The classification and retry strategy may be too complex.
|
||||
The configuration and configuration UI may be too complex.
|
||||
Implementation-dependent.
|
||||
|
||||
It is not required to support ElGamal and hybrid algorithms on the same destination.
|
||||
ElGamal is obsolete, and ElGamal + hybrid only (no X25519) doesn't make much sense.
|
||||
Also, ElGamal and Hybrid New Session Messages are both large, so
|
||||
classification strategies would often have to try both decryptions,
|
||||
which would be inefficient.
|
||||
Implementation-dependent.
|
||||
|
||||
Clients may use the same or different X25519 static keys for the X25519
|
||||
and the hybrid protocols on the same tunnels, implementation-dependent.
|
||||
|
||||
|
||||
Forward Secrecy
|
||||
---------------
|
||||
The ECIES specification allows Garlic Messages in the New Session Message payload,
|
||||
which allows for 0-RTT delivery of the initial streaming packet,
|
||||
usually a HTTP GET, together with the client's leaseset.
|
||||
However, the New Session Message payload does not have forward secrecy.
|
||||
As this proposal is emphasizing enhanced forward secrecy for ratchet,
|
||||
implementations may or should defer inclusion of the streaming payload,
|
||||
or the full streaming message, until the first Existing Session Message.
|
||||
This would be at the expense of 0-RTT delivery.
|
||||
Strategies may also depend on traffic type or tunnel type,
|
||||
or on GET vs. POST, for example.
|
||||
Implementation-dependent.
|
||||
|
||||
|
||||
New Session Size
|
||||
----------------
|
||||
MLKEM will dramatically increase
|
||||
the size of the New Session Message, as described above.
|
||||
This may significantly decrease the reliability of New Session Message
|
||||
delivery through tunnels, where they must be fragmented into
|
||||
multiple 1024 byte tunnel messages. Delivery success is
|
||||
proportional to the exponential number of fragments.
|
||||
Implementations may use various strategies to limit the size of the message,
|
||||
at the expense of 0-RTT delivery.
|
||||
Implementation-dependent.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [CLOUDFLARE]
|
||||
https://blog.cloudflare.com/pq-2024/
|
||||
|
||||
.. [COMMON]
|
||||
{{ spec_url('common-structures') }}
|
||||
|
||||
.. [ECIES]
|
||||
{{ spec_url('ecies') }}
|
||||
|
||||
.. [FORUM]
|
||||
http://zzz.i2p/topics/3294
|
||||
|
||||
.. [FIPS202]
|
||||
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
|
||||
.. [FIPS203]
|
||||
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf
|
||||
|
||||
.. [NIST-PQ-END]
|
||||
https://www.nccoe.nist.gov/sites/default/files/2023-08/pqc-light-at-the-end-of-the-tunnel-presentation.pdf
|
||||
|
||||
.. [NIST-VECTORS]
|
||||
https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
|
||||
|
||||
.. [Noise]
|
||||
https://noiseprotocol.org/noise.html
|
||||
|
||||
.. [Noise-Hybrid]
|
||||
https://github.com/noiseprotocol/noise_hfs_spec/blob/master/output/noise_hfs.pdf
|
||||
|
||||
.. [OPENSSL]
|
||||
https://openssl-library.org/post/2025-02-04-release-announcement-3.5/
|
||||
|
||||
.. [PQ-WIREGUARD]
|
||||
https://eprint.iacr.org/2020/379.pdf
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
@ -3,8 +3,8 @@ ECIES-X25519 Router Messages
|
||||
=============================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-03
|
||||
:accuratefor: 0.9.65
|
||||
:lastupdated: 2021-01
|
||||
:accuratefor: 0.9.49
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -271,7 +271,7 @@ This is the same as specified in [Tunnel-Creation-ECIES]_ and [Prop152]_ for tun
|
||||
//chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
plaintext = 464 byte build request record
|
||||
ad = h
|
||||
|
@ -3,26 +3,25 @@ ECIES-X25519-AEAD-Ratchet
|
||||
=========================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
:lastupdated: 2020-11
|
||||
:accuratefor: 0.9.47
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Note
|
||||
====
|
||||
Network deployment complete.
|
||||
Network deployment and testing in progress.
|
||||
Subject to minor revisions.
|
||||
See [Prop144]_ for the original proposal, including background discussion and additional information.
|
||||
|
||||
The following features are not implemented as of 0.9.66:
|
||||
The following features are not implemented as of 0.9.46:
|
||||
|
||||
- MessageNumbers, Options, and Termination blocks
|
||||
- Protocol-layer responses
|
||||
- Zero static key
|
||||
- Multicast
|
||||
|
||||
For the MLKEM PQ Hybrid version of this protocol, see [ECIES-HYBRID]_.
|
||||
|
||||
|
||||
Overview
|
||||
@ -183,44 +182,6 @@ Bound sessions are similar to the Noise IK pattern.
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Security Properties
|
||||
```````````````````
|
||||
|
||||
Using Noise terminology, the establishment and data sequence is as follows:
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
IK(s, rs): Authentication Confidentiality
|
||||
<- s
|
||||
...
|
||||
-> e, es, s, ss 1 2
|
||||
<- e, ee, se 2 4
|
||||
-> 2 5
|
||||
<- 2 5
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Differences From XK
|
||||
```````````````````
|
||||
IK handshakes have several differences from XK handshakes used
|
||||
in [NTCP2]_ and [SSU2]_.
|
||||
|
||||
- Four total DH operations compared to three for XK
|
||||
- Sender authentication in first message: The payload is authenticated
|
||||
as belonging to the owner of the sender's public key, although
|
||||
the key could have been compromised (Authentication 1)
|
||||
XK requires another round trip before Alice is authenticated.
|
||||
- Full forward secrecy (Confidentiality 5) after the second message.
|
||||
Bob may send a payload immediately after the second message with
|
||||
full forward secrecy.
|
||||
XK requires another round trip for full forward secrecy.
|
||||
|
||||
In summary, IK allows 1-RTT delivery of the response payload from Bob to Alice
|
||||
with full forward secrecy, however the request payload is not forward-secret.
|
||||
|
||||
|
||||
Sessions
|
||||
--------
|
||||
|
||||
@ -931,7 +892,7 @@ This is the "e" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
@ -975,7 +936,7 @@ This is the "ss" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -995,7 +956,7 @@ KDF for Payload Section (without Alice static key)
|
||||
Note that this is a Noise "N" pattern, but we use the same "IK" initializer
|
||||
as for bound sessions.
|
||||
|
||||
New Session messages can not be identified as containing Alice's static key or not
|
||||
New Session essages can not be identified as containing Alice's static key or not
|
||||
until the static key is decrypted and inspected to determine if it contains all zeros.
|
||||
Therefore, the receiver must use the "IK" state machine for all
|
||||
New Session messages.
|
||||
@ -1180,7 +1141,7 @@ KDF for Reply Key Section Encrypted Contents
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
||||
@ -2182,13 +2143,10 @@ a single frame, but it is not prohibited.
|
||||
DateTime
|
||||
````````
|
||||
An expiration.
|
||||
Assists in replay prevention.
|
||||
Assists in reply prevention.
|
||||
Bob must validate that the message is recent, using this timestamp.
|
||||
Bob must implement a Bloom filter or other mechanism to prevent replay attacks,
|
||||
if the time is valid.
|
||||
Bob may also use an earlier replay detection check for a duplicate ephemeral key
|
||||
(either pre- or post-Elligator2 decode) to detect and drop recent duplicate NS messages
|
||||
before decryption.
|
||||
Generally included in New Session messages only.
|
||||
|
||||
.. raw:: html
|
||||
@ -3041,24 +2999,8 @@ non-mod-16 padding, things will need to be done differently.
|
||||
|
||||
|
||||
|
||||
Retransmissions and State Transistions
|
||||
--------------------------------------
|
||||
|
||||
The ratchet layer does not do retransmissions, and with two exceptions,
|
||||
does not use timers for tranmssions. Timers are also required
|
||||
for tagset timeout.
|
||||
|
||||
Transmission timers are used only for sending NSR and for
|
||||
replying with an ES when a received ES contains an ACK request.
|
||||
Recommended timeout is one second. In almost all cases, the
|
||||
higher layer (datagram or streaming) will reply, forcing
|
||||
a NSR or ES, and the timer may be cancelled.
|
||||
If the timer does fire, send an empty payload with the NSR or ES.
|
||||
|
||||
|
||||
|
||||
Ratchet-layer Responses
|
||||
````````````````````````
|
||||
Protocol-layer Responses
|
||||
-------------------------
|
||||
|
||||
Initial implementations rely on bidirectional traffic at the higher layers.
|
||||
That is, the implementations assume that traffic in the opposite direction
|
||||
@ -3070,7 +3012,7 @@ such that there is no higher-layer traffic to generate a timely response.
|
||||
Receipt of NS and NSR messages require a response;
|
||||
receipt of ACK Request and Next Key blocks also require a response.
|
||||
|
||||
Implementations should start a timer when one of these
|
||||
A sophisticated implementation may start a timer when one of these
|
||||
messages is received which requires a response,
|
||||
and generate an "empty" (no Garlic Clove block) response
|
||||
at the ECIES layer
|
||||
@ -3081,130 +3023,6 @@ responses to NS and NSR messages, to shift the traffic to
|
||||
the efficient ES messages as soon as possible.
|
||||
|
||||
|
||||
NS Binding For NSR
|
||||
``````````````````
|
||||
|
||||
At the ratchet layer, as Bob, Alice is only known by static key.
|
||||
The NS message is authenticated ([Noise]_ IK sender authentication 1).
|
||||
However, this is not sufficient for the ratchet layer to be able to send anything
|
||||
to Alice, as network routing requires a full Destination.
|
||||
|
||||
Before the NSR may be sent, Alice's full Destination must be discovered either
|
||||
by the ratchet layer or a higher-layer repliable protocol,
|
||||
either repliable [Datagrams]_ or [Streaming]_.
|
||||
After finding the Leaseset for that Destination, that Leaseset
|
||||
will contain the same static key as contained in the NS.
|
||||
|
||||
Typically, the higher layer will respond, forcing a network database
|
||||
lookup of Alice's Leaseset by Alice's Destination Hash.
|
||||
That Leaseset will almost always be found locally, because the
|
||||
NS contained a Garlic Clove block, containing a Database Store message,
|
||||
containing Alice's Leaseset.
|
||||
|
||||
For Bob to be prepared to send a ratchet-layer NSR, and to bind
|
||||
the pending session to Alice's Destination, Bob should
|
||||
"capture" the Destination while processing the NS payload.
|
||||
If a Database Store message is found containing a Leaseset
|
||||
with a key matching the static key in the NS,
|
||||
the pending session is now bound to that Destination,
|
||||
and Bob knows where to send any NSR if the response timer expires.
|
||||
This is the recommended implementation.
|
||||
|
||||
An alternative design is to maintain a cache or database
|
||||
where the static key is mapped to a Destination.
|
||||
The security and practicality of this approach
|
||||
is a topic for further study.
|
||||
|
||||
Neither this specification nor others strictly require that
|
||||
every NS contains Alice's Leaseset.
|
||||
However, in practice, it should.
|
||||
The recommended ES tagset sender timeout (8 minutes)
|
||||
is shorter than the maximum Leaseset timeout (10 minutes),
|
||||
so there could be a small window where the previous session
|
||||
has expired, Alice thinks that Bob
|
||||
still has her valid Leaseset, and does not send a new Leaseset
|
||||
with the new NS. This is a topic for further study.
|
||||
|
||||
|
||||
Multiple NS Messages
|
||||
````````````````````
|
||||
|
||||
If no NSR response is received before the higher layer (datagram or streaming)
|
||||
sends more data, possibly as a retransmission, Alice must compose a new NS, using a new ephemeral key.
|
||||
Do not reuse the ephemeral key from any previous NS.
|
||||
Alice must maintain the additional handshake state and derived receive tagset,
|
||||
to receive NSR messages in reply to any NSR that was sent.
|
||||
|
||||
Implementations may limit the total number of NS messages sent,
|
||||
or the rate of NS message sending,
|
||||
either by queueing or dropping higher layer messages before they are sent.
|
||||
|
||||
In certain situations, when under high load, or under certain attack scenarios,
|
||||
it may be appropriate for Bob to queue, drop, or limit apparent NS messages without attempting to decrypt,
|
||||
to avoid a resource exhaustion attack.
|
||||
|
||||
For each NS received, Bob generates an NSR outbund tagset, sends an NSR, does a split(),
|
||||
and generates the inbound and outbound ES tagsets.
|
||||
However, Bob does not send any ES messages until the first ES message
|
||||
on the corresponding inbound tagset is received. After that, Bob may discard
|
||||
all handshake states and tagsets for any other NS received or NSR sent, or allow
|
||||
them to expire shortly. Do not use NSR tagsets for ES messages.
|
||||
|
||||
It is a topic for further study if Bob may choose to speculatively send ES messages immediately after
|
||||
the NSR, even before receiving the first ES from Alice.
|
||||
In certain scenarios and traffic patterns, this could save substantial
|
||||
bandwidth and CPU.
|
||||
This strategy may be based on heuristics such as traffic patterns,
|
||||
percentage of ESs received on the first session's tagset, or other data.
|
||||
|
||||
|
||||
|
||||
Multiple NSR Messages
|
||||
`````````````````````
|
||||
|
||||
For each NS message received, until an ES message is received, Bob must reply
|
||||
with a new NSR, either due to higher layer traffic being sent, or NSR send timer expiration.
|
||||
|
||||
Each NSR uses the handshake state and tagset corresponding to the incoming NS.
|
||||
Bob must maintain the handshake state and tagest for all NS messages received, until
|
||||
an ES message is received.
|
||||
|
||||
Implementations may limit the total number of NSR messages sent,
|
||||
or the rate of NSR message sending,
|
||||
either by queueing or dropping higher layer messages before they are sent.
|
||||
These may be limited either when caused by incoming NS messages, or
|
||||
additional higher layer outbound traffic.
|
||||
|
||||
In certain situations, when under high load, or under certain attack scenarios,
|
||||
it may be appropriate for Alice to queue, drop, or limit NSR messages
|
||||
without attempting to decrypt, to avoid a resource exhaustion attack.
|
||||
These limits may be either total across all sessions, per session, or both.
|
||||
|
||||
Once Alice receives an NSR, Alice does a split() to derive the ES session keys.
|
||||
Alice should set a timer, and send an empty ES message if the higher layer does
|
||||
not send any traffic, typically within one second.
|
||||
|
||||
The other inbound NSR tagsets may be removed soon or allowed
|
||||
to expire, but Alice should keep them for a short while, to
|
||||
decrypt any other NSR messages that are received.
|
||||
|
||||
|
||||
Replay Prevention
|
||||
-----------------
|
||||
|
||||
Bob must implement a Bloom filter or other mechanism to prevent NS replay attacks,
|
||||
if the included DateTime is recent, and reject NS messages where the
|
||||
DateTime is too old.
|
||||
Bob may also have use an earlier replay detection check for a duplicate ephemeral key
|
||||
(either pre- or post-Elligator2 decode) to detect and drop recent duplicate NS messages
|
||||
before decryption.
|
||||
|
||||
NSR and ES messages have inherent replay prevention because the
|
||||
session tag is one-time-use.
|
||||
|
||||
Garlic messages also have replay prevention if the router implements
|
||||
a router-wide Bloom filter based on I2NP message ID.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3252,12 +3070,6 @@ References
|
||||
.. [CRYPTO-ELG]
|
||||
{{ site_url('docs/how/cryptography', True) }}#elgamal
|
||||
|
||||
.. [ECIES-HYBRID]
|
||||
{{ spec_url('ecies-hybrid') }}
|
||||
|
||||
.. [Datagrams]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
.. [Elligator2]
|
||||
https://elligator.cr.yp.to/elligator-20130828.pdf
|
||||
https://www.imperialviolet.org/2013/12/25/elligator.html
|
||||
@ -3329,12 +3141,6 @@ References
|
||||
.. [SSU]
|
||||
{{ site_url('docs/transport/ssu', True) }}
|
||||
|
||||
.. [SSU2]
|
||||
{{ spec_url('ssu2') }}
|
||||
|
||||
.. [Streaming]
|
||||
{{ spec_url('streaming') }}
|
||||
|
||||
.. [STS]
|
||||
Diffie, W.; van Oorschot P. C.; Wiener M. J., Authentication and
|
||||
Authenticated Key Exchanges
|
||||
|
@ -3,8 +3,8 @@ Encrypted LeaseSet Specification
|
||||
================================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: June 2019
|
||||
:accuratefor: 0.9.41
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@ -3,8 +3,8 @@ Access Filter Format Specification
|
||||
==================================
|
||||
.. meta::
|
||||
:category: Formats
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: April 2019
|
||||
:accuratefor: 0.9.40
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@ -3,8 +3,8 @@ GeoIP File Specification
|
||||
========================
|
||||
.. meta::
|
||||
:category: Formats
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: December 2013
|
||||
:accuratefor: 0.9.9
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -12,12 +12,6 @@ GeoIP File Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
NOTE: OBSOLETE - We now support three formats, in order of preference:
|
||||
|
||||
- Maxmind geoip2 (GeoLite2-Country.mmdb) bundled with all installs except Debian packages and Android
|
||||
- Maxmind geoip1 (GeoIP.dat) in the Debian geoip-database package
|
||||
- The IPv4 Tor format (geoip.txt) and the custom IPv6 format (geoipv6.dat.gz) documented below, still supported but unused.
|
||||
|
||||
This page specifies the format of the various GeoIP files,
|
||||
used by the router to look up a country for an IP.
|
||||
|
||||
|
@ -3,8 +3,8 @@ I2CP Specification
|
||||
==================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2023-10
|
||||
:accuratefor: 0.9.59
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -12,21 +12,13 @@ I2CP Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
This is the specification of the I2P Control Protocol (I2CP), the low-level interface
|
||||
This page specified the I2P Control Protocol (I2CP), which is the interface
|
||||
between clients and the router. Java clients will use the I2CP client API,
|
||||
which implements this protocol.
|
||||
which implements this protocol. Non-Java clients will most likely use a
|
||||
higher-layer protocol such as SAM or BOB.
|
||||
|
||||
There are no known non-Java implementations of a client-side library
|
||||
that implements I2CP. Additionally, socket-oriented (streaming) applications would need
|
||||
an implementation of the streaming protocol, but there are no non-Java libraries for that either.
|
||||
Therefore, non-Java clients should instead use the higher-layer protocol SAM [SAMv3]_,
|
||||
for which libraries exist in several languages.
|
||||
|
||||
This is a low-level protocol supported both internally and externally
|
||||
by the Java I2P router.
|
||||
The protocol is only serialized if the client and router are not in the same
|
||||
JVM; otherwise, I2CP message Java objects are passed via an internal JVM interface.
|
||||
I2CP is also supported externally by the C++ router i2pd.
|
||||
JVM; otherwise, I2CP message objects are passed via an internal JVM interface.
|
||||
|
||||
More information is on the I2CP Overview page [I2CP]_.
|
||||
|
||||
@ -46,9 +38,8 @@ It also appears that there are some provisions for a single client to talk to
|
||||
multiple routers over separate connections. This is also untested, and probably
|
||||
not useful.
|
||||
|
||||
There is no way for a session to be maintained
|
||||
It does not appear that there is currently a way for a session to be maintained
|
||||
after a disconnect, or to be recovered on a different I2CP connection.
|
||||
When the socket is closed, the session is destroyed.
|
||||
|
||||
|
||||
Example Message Sequences
|
||||
@ -150,7 +141,7 @@ Existing session, with i2cp.fastReceive=true (as of 0.9.4)
|
||||
Message Payload Message <---------------------
|
||||
{% endhighlight %}
|
||||
|
||||
Existing session, with i2cp.fastReceive=false (DEPRECATED)
|
||||
Existing session, with i2cp.fastReceive=false
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -213,6 +204,13 @@ responses. DestLookup and DestReply do not contain Session IDs; use the newer
|
||||
HostLookup and HostReply instead. GetBandwidthLimts and BandwidthLimits do not
|
||||
contain session IDs, however the response is not session-specific.
|
||||
|
||||
Support for multiple sessions is preliminary and subject to change. Support
|
||||
may not be complete in other parts of the API and user interface, particularly
|
||||
streaming and i2ptunnel. Current support is primarily for clients (i.e.
|
||||
Destinations that do not publish their leaseset or accept incoming
|
||||
connections), and is incomplete and untested for servers. Future releases may
|
||||
provide additional features and options.
|
||||
|
||||
|
||||
.. _notes:
|
||||
|
||||
@ -237,10 +235,6 @@ below.
|
||||
============== ======================
|
||||
Version Required I2CP Features
|
||||
============== ======================
|
||||
0.9.66 Host lookup/reply extensions (see proposal 167)
|
||||
|
||||
0.9.62 MessageStatus message Loopback error code
|
||||
|
||||
0.9.43 BlindingInfo message supported
|
||||
|
||||
Additional HostReply message failure codes
|
||||
@ -452,7 +446,7 @@ Message Types
|
||||
=============================== ========= ==== =====
|
||||
BandwidthLimitsMessage_ R -> C 23 0.7.2
|
||||
BlindingInfoMessage_ C -> R 42 0.9.43
|
||||
CreateLeaseSetMessage_ C -> R 4 deprecated
|
||||
CreateLeaseSetMessage_ C -> R 4
|
||||
CreateLeaseSet2Message_ C -> R 41 0.9.39
|
||||
CreateSessionMessage_ C -> R 1
|
||||
DestLookupMessage_ C -> R 34 0.7
|
||||
@ -465,11 +459,11 @@ HostLookupMessage_ C -> R 38 0.9.11
|
||||
HostReplyMessage_ R -> C 39 0.9.11
|
||||
MessagePayloadMessage_ R -> C 31
|
||||
MessageStatusMessage_ R -> C 22
|
||||
ReceiveMessageBeginMessage_ C -> R 6 deprecated
|
||||
ReceiveMessageEndMessage_ C -> R 7 deprecated
|
||||
ReceiveMessageBeginMessage_ C -> R 6
|
||||
ReceiveMessageEndMessage_ C -> R 7
|
||||
ReconfigureSessionMessage_ C -> R 2 0.7.1
|
||||
ReportAbuseMessage_ bidir. 29 deprecated
|
||||
RequestLeaseSetMessage_ R -> C 21 deprecated
|
||||
ReportAbuseMessage_ bidir. 29
|
||||
RequestLeaseSetMessage_ R -> C 21
|
||||
RequestVariableLeaseSetMessage_ R -> C 37 0.9.7
|
||||
SendMessageMessage_ C -> R 5
|
||||
SendMessageExpiresMessage_ C -> R 36 0.7.1
|
||||
@ -501,11 +495,9 @@ Contents
|
||||
|
||||
Notes
|
||||
`````
|
||||
The client limits may be the only values set, and may be the
|
||||
actual router limits, or a percentage of the router limits, or specific to
|
||||
the particular client, implementation-dependent.
|
||||
All the values labeled as router limits may be 0, implementation-dependent.
|
||||
As of release 0.7.2.
|
||||
Currently, the client limits are the only values set, and are actually the
|
||||
router limits. All the values labeled as router limits are always 0. As of
|
||||
release 0.7.2.
|
||||
|
||||
|
||||
.. _msg-BlindingInfo:
|
||||
@ -602,11 +594,6 @@ Notes
|
||||
CreateLeaseSetMessage
|
||||
---------------------
|
||||
|
||||
DEPRECATED. Cannot be used for LeaseSet2, offline keys, non-ElGamal encryption types,
|
||||
multiple encryption types, or encrypted LeaseSets.
|
||||
Use CreateLeaseSet2Message with all routers 0.9.39 or higher.
|
||||
|
||||
|
||||
Description
|
||||
```````````
|
||||
This message is sent in response to a RequestLeaseSetMessage_ or
|
||||
@ -661,7 +648,7 @@ Contents
|
||||
1. `Session ID`_
|
||||
2. One byte type of lease set to follow.
|
||||
|
||||
- Type 1 is a [LeaseSet]_ (deprecated)
|
||||
- Type 1 is a [LeaseSet]_
|
||||
- Type 3 is a [LeaseSet2]_
|
||||
- Type 5 is a [EncryptedLeaseSet]_
|
||||
- Type 7 is a [MetaLeaseSet]_
|
||||
@ -889,24 +876,7 @@ Contents
|
||||
2. 4 byte [Integer]_ request ID
|
||||
3. 4 byte [Integer]_ timeout (ms)
|
||||
4. 1 byte [Integer]_ request type
|
||||
5. SHA-256 [Hash]_ or host name [String]_ or [Destination]_
|
||||
|
||||
Request types:
|
||||
|
||||
==== =================== =======
|
||||
Type Lookup key (item 5) As of
|
||||
==== =================== =======
|
||||
0 Hash
|
||||
1 host name String
|
||||
2 Hash 0.9.66
|
||||
3 host name String 0.9.66
|
||||
4 Destination 0.9.66
|
||||
==== =================== =======
|
||||
|
||||
Types 2-4 request that the options mapping from the LeaseSet
|
||||
be returned in the HostReply message.
|
||||
See proposal 167.
|
||||
|
||||
5. SHA-256 [Hash]_ or host name [String]_
|
||||
|
||||
Notes
|
||||
`````
|
||||
@ -919,6 +889,8 @@ Notes
|
||||
the future it may also be useful for remote naming service lookups. The value
|
||||
may be not be honored for local host name lookups, which should be fast.
|
||||
|
||||
* The request type is 0 for Hash and 1 for host name.
|
||||
|
||||
* Base 32 host name lookup is supported but it is preferred to convert it to a
|
||||
Hash first.
|
||||
|
||||
@ -943,44 +915,8 @@ Contents
|
||||
- 3: Private key required (as of 0.9.43)
|
||||
- 4: Lookup password and private key required (as of 0.9.43)
|
||||
- 5: Leaseset decryption failure (as of 0.9.43)
|
||||
- 6: Leaseset lookup failure (as of 0.9.66)
|
||||
- 7: Lookup type unsupported (as of 0.9.66)
|
||||
|
||||
4. [Destination]_, only present if result code is zero,
|
||||
except may also be returned for lookup types 2-4.
|
||||
See below.
|
||||
|
||||
5. [Mapping]_, only present if result code is zero,
|
||||
only returned for lookup types 2-4.
|
||||
As of 0.9.66. See below.
|
||||
|
||||
|
||||
Responses for lookup types 2-4
|
||||
``````````````````````````````
|
||||
Proposal 167 defines additional lookup types that
|
||||
return all options from the leaseset, if present.
|
||||
For lookup types 2-4, the router must fetch the leaseset,
|
||||
even if the lookup key is in the address book.
|
||||
|
||||
If successful, the HostReply will contain the options Mapping
|
||||
from the leaseset, and includes it as item 5 after the destination.
|
||||
If there are no options in the Mapping, or the leaseset was version 1,
|
||||
it will still be included as an empty Mapping (two bytes: 0 0).
|
||||
All options from the leaseset will be included, not just service record options.
|
||||
For example, options for parameters defined in the future may be present.
|
||||
The returned Mapping may or may not be sorted, implementation-dependent.
|
||||
|
||||
On leaseset lookup failure, the reply will contain a new error code 6 (Leaseset lookup failure)
|
||||
and will not include a mapping.
|
||||
When error code 6 is returned, the Destination field may or may not be present.
|
||||
It will be present if a hostname lookup in the address book was successful,
|
||||
or if a previous lookup was successful and the result was cached,
|
||||
or if the Destination was present in the lookup message (lookup type 4).
|
||||
|
||||
If a lookup type is not supported,
|
||||
the reply will contain a new error code 7 (lookup type unsupported).
|
||||
|
||||
|
||||
4. [Destination]_, only present if result code is zero.
|
||||
|
||||
Notes
|
||||
`````
|
||||
@ -993,9 +929,6 @@ Notes
|
||||
As of 0.9.43, the additional failure codes 2-5 were defined
|
||||
to support extended errors for "b33" lookups.
|
||||
See proposals 123 and 149 for additional information.
|
||||
As of 0.9.66, the additional failure codes 6-7 were defined
|
||||
to support extended errors for type 2-4 lookups.
|
||||
See proposal 167 for additional information.
|
||||
|
||||
.. _msg-MessagePayload:
|
||||
|
||||
@ -1050,16 +983,13 @@ router implementation uses the guaranteed status codes, not the best effort
|
||||
codes.
|
||||
|
||||
As of router version 0.9.5, additional status codes are defined, however they
|
||||
are not necessarily implemented. See [MSM-JAVADOCS]_ for details.
|
||||
For outgoing messages, the codes 1, 2, 4, and 6 indicate success; all others are failures.
|
||||
Returned failure codes may vary and are implementation-specific.
|
||||
|
||||
All status codes:
|
||||
are not necessarily implemented. See [MSM-JAVADOCS]_ for details. All status
|
||||
codes:
|
||||
|
||||
=========== ============= ====================== ==========================================================
|
||||
Status Code As Of Release Name Description
|
||||
=========== ============= ====================== ==========================================================
|
||||
0 Available DEPRECATED. For incoming messages only. All other status codes below
|
||||
0 Available For incoming messages only. All other status codes below
|
||||
are for outgoing messages.
|
||||
|
||||
The included size is the size in bytes of the available
|
||||
@ -1165,11 +1095,6 @@ Status Code As Of Release Name Description
|
||||
|
||||
This is a guaranteed failure.
|
||||
|
||||
23 0.9.62 Loopback Denied The message was attempted to be sent from and to
|
||||
the same destination or session.
|
||||
|
||||
This is a guaranteed failure.
|
||||
|
||||
=========== ============= ====================== ==========================================================
|
||||
|
||||
When status = 1 (accepted), the nonce matches the nonce in the
|
||||
@ -1181,8 +1106,6 @@ success or failure notification. Otherwise, the nonce may be ignored.
|
||||
ReceiveMessageBeginMessage
|
||||
--------------------------
|
||||
|
||||
DEPRECATED. Not supported by i2pd.
|
||||
|
||||
Description
|
||||
```````````
|
||||
Request the router to deliver a message that it was previously notified of.
|
||||
@ -1209,8 +1132,6 @@ This is unused in "fast receive" mode, which is the default as of release
|
||||
ReceiveMessageEndMessage
|
||||
------------------------
|
||||
|
||||
DEPRECATED. Not supported by i2pd.
|
||||
|
||||
Description
|
||||
```````````
|
||||
Tell the router that delivery of a message was completed successfully and that
|
||||
@ -1261,19 +1182,11 @@ Notes
|
||||
changes here will not be recognized by the router. Changes to tunnel options
|
||||
inbound.* and outbound.* are always recognized.
|
||||
|
||||
* In general, the router should merge the updated config with the current config,
|
||||
so the updated config only needs to contain the new or changed options.
|
||||
However, because of the merge, options may not be removed in this manner;
|
||||
they must be set explicitly to the desired default value.
|
||||
|
||||
|
||||
.. _msg-ReportAbuse:
|
||||
|
||||
ReportAbuseMessage
|
||||
------------------
|
||||
|
||||
DEPRECATED, UNUSED, UNSUPPORTED
|
||||
|
||||
Description
|
||||
```````````
|
||||
Tell the other party (client or router) that they are under attack, potentially
|
||||
@ -1302,21 +1215,12 @@ ReportAbuseMessage_, but neither has a handler for the message when received.
|
||||
RequestLeaseSetMessage
|
||||
----------------------
|
||||
|
||||
DEPRECATED. Not supported by i2pd. Not sent by Java I2P to clients version
|
||||
0.9.7 or higher (2013-07). Use RequestVariableLeaseSetMessage.
|
||||
|
||||
Description
|
||||
```````````
|
||||
Request that a client authorize the inclusion of a particular set of inbound
|
||||
tunnels. Sent from Router to Client. The client responds with a
|
||||
CreateLeaseSetMessage_.
|
||||
|
||||
The first of these messages sent on a session is a signal to the client
|
||||
that tunnels are built and ready for traffic. The router must not
|
||||
send the first of these messages until at least one inbound AND one outbound tunnel
|
||||
have been built. Clients should timeout and destroy the session if the first
|
||||
of these messages is not received after some time (recommended: 5 minutes or more).
|
||||
|
||||
Contents
|
||||
````````
|
||||
1. `Session ID`_
|
||||
@ -1330,9 +1234,9 @@ Contents
|
||||
|
||||
Notes
|
||||
`````
|
||||
This requests a [LeaseSet]_ with all [Lease]_ entries set to expire at the same time.
|
||||
This requests a [LeaseSet]_ with all [Leases]_ set to expire at the same time.
|
||||
For client versions 0.9.7 or higher, RequestVariableLeaseSetMessage_ is
|
||||
used.
|
||||
preferred.
|
||||
|
||||
.. _msg-RequestVariableLeaseSet:
|
||||
|
||||
@ -1346,17 +1250,11 @@ tunnels.
|
||||
|
||||
Sent from Router to Client. The client responds with a CreateLeaseSetMessage_ or CreateLeaseSet2Message_.
|
||||
|
||||
The first of these messages sent on a session is a signal to the client
|
||||
that tunnels are built and ready for traffic. The router must not
|
||||
send the first of these messages until at least one inbound AND one outbound tunnel
|
||||
have been built. Clients should timeout and destroy the session if the first
|
||||
of these messages is not received after some time (recommended: 5 minutes or more).
|
||||
|
||||
Contents
|
||||
````````
|
||||
1. `Session ID`_
|
||||
2. 1 byte [Integer]_ number of tunnels
|
||||
3. That many [Lease]_ entries
|
||||
3. That many [Leases]_
|
||||
|
||||
Notes
|
||||
`````
|
||||
@ -1505,7 +1403,6 @@ Bit 8
|
||||
Bits 7-4
|
||||
Low tag threshold. If there are less than this many tags available, send
|
||||
more. This is advisory and does not force tags to be delivered.
|
||||
For ElGamal only. Ignored for ECIES-Ratchet.
|
||||
|
||||
=========== =============
|
||||
Field value Tag threshold
|
||||
@ -1531,7 +1428,6 @@ Field value Tag threshold
|
||||
Bits 3-0
|
||||
Number of tags to send if required. This is advisory and does not force
|
||||
tags to be delivered.
|
||||
For ElGamal only. Ignored for ECIES-Ratchet.
|
||||
|
||||
=========== ============
|
||||
Field value Tags to send
|
||||
@ -1563,11 +1459,8 @@ Description
|
||||
```````````
|
||||
Instruct the client as to the status of its session.
|
||||
|
||||
Sent from Router to Client, in response to a CreateSessionMessage_,
|
||||
Sent from Router to Client, possibly in response to a CreateSessionMessage_,
|
||||
ReconfigureSessionMessage_, or DestroySessionMessage_.
|
||||
In all cases, including in response to CreateSessionMessage_,
|
||||
the router should respond immediately (do not wait for tunnels to be built).
|
||||
|
||||
|
||||
Contents
|
||||
````````
|
||||
@ -1661,6 +1554,7 @@ References
|
||||
.. [Integer]
|
||||
{{ ctags_url('Integer') }}
|
||||
|
||||
.. [Leases]
|
||||
.. [Lease]
|
||||
{{ ctags_url('Lease') }}
|
||||
|
||||
@ -1688,9 +1582,6 @@ References
|
||||
.. [RouterIdentity]
|
||||
{{ ctags_url('RouterIdentity') }}
|
||||
|
||||
.. [SAMv3]
|
||||
{{ site_url('docs/api/samv3') }}
|
||||
|
||||
.. [Signature]
|
||||
{{ ctags_url('Signature') }}
|
||||
|
||||
|
@ -3,8 +3,8 @@ I2NP Specification
|
||||
==================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2023-10
|
||||
:accuratefor: 0.9.59
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -45,18 +45,6 @@ below.
|
||||
============== ================================================================
|
||||
API Version Required I2NP Features
|
||||
============== ================================================================
|
||||
0.9.66 LeaseSet2 service record options (see proposal 167)
|
||||
|
||||
0.9.65 Tunnel build bandwidth parameters (see proposal 168)
|
||||
|
||||
0.9.59 Minimum peers will build tunnels through, as of 0.9.63
|
||||
|
||||
Minimum floodfill peers will send DSM to, as of 0.9.63
|
||||
|
||||
0.9.58 Minimum peers will build tunnels through, as of 0.9.62
|
||||
|
||||
ElGamal Routers deprecated
|
||||
|
||||
0.9.55 SSU2 transport support (if published in router info)
|
||||
|
||||
0.9.51 Short tunnel build messages for ECIES-X25519 routers
|
||||
@ -158,23 +146,12 @@ Common header to all I2NP messages, which contains important information like a
|
||||
|
||||
Contents
|
||||
````````
|
||||
|
||||
There are three separate formats used, depending on context;
|
||||
one standard format, and two short format.
|
||||
|
||||
The standard 16 byte format contains
|
||||
1 byte [Integer]_ specifying the type of this message, followed by a 4 byte
|
||||
[Integer]_ specifying the message-id. After that there is an expiration
|
||||
[Date]_, followed by a 2 byte [Integer]_ specifying the length of the message
|
||||
payload, followed by a [Hash]_, which is truncated to the first byte. After
|
||||
that the actual message data follows.
|
||||
|
||||
The short formats use a 4 byte expiration in seconds instead of an
|
||||
8 byte expiration in milliseconds.
|
||||
The short formats do not contain a checksum or size,
|
||||
those are provided by the encapsulations, depending on context.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
@ -186,13 +163,13 @@ Standard (16 bytes):
|
||||
| size |chks|
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Short (SSU, 5 bytes) (obsolete):
|
||||
Short (SSU, 5 bytes):
|
||||
|
||||
+----+----+----+----+----+
|
||||
|type| short_expiration |
|
||||
+----+----+----+----+----+
|
||||
|
||||
Short (NTCP2, SSU2, and ECIES-Ratchet Garlic Cloves, 9 bytes):
|
||||
Short (NTCP2 and SSU2, 9 bytes):
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|type| msg_id | short_expira-
|
||||
@ -261,9 +238,6 @@ Notes
|
||||
BuildRequestRecord
|
||||
------------------
|
||||
|
||||
DEPRECATED, only used in the current network when a tunnel contains an ElGamal router.
|
||||
See [TUNNEL-CREATION-ECIES]_.
|
||||
|
||||
Description
|
||||
```````````
|
||||
One Record in a set of multiple records to request the creation of one hop in
|
||||
@ -441,9 +415,6 @@ Notes
|
||||
BuildResponseRecord
|
||||
-------------------
|
||||
|
||||
DEPRECATED, only used in the current network when a tunnel contains an ElGamal router.
|
||||
See [TUNNEL-CREATION-ECIES]_.
|
||||
|
||||
Description
|
||||
```````````
|
||||
One Record in a set of multiple records with responses to a build request.
|
||||
@ -525,11 +496,6 @@ See [TUNNEL-CREATION-ECIES]_.
|
||||
GarlicClove
|
||||
-----------
|
||||
|
||||
Warning: This is the format used for garlic cloves within ElGamal-encrypted garlic messages [CRYPTO-ELG]_.
|
||||
The format for ECIES-AEAD-X25519-Ratchet garlic messages and garlic cloves
|
||||
is significantly different; see [ECIES]_ for the specification.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
@ -586,25 +552,17 @@ Notes
|
||||
* The Clove ID is generally set to a random number on transmit and is checked
|
||||
for duplicates on receive (same message ID space as top-level Message IDs)
|
||||
|
||||
|
||||
.. _struct-GarlicCloveDeliveryInstructions:
|
||||
|
||||
Garlic Clove Delivery Instructions
|
||||
----------------------------------
|
||||
|
||||
This is the format used for both ElGamal-encrypted [CRYPTO-ELG]_
|
||||
and ECIES-AEAD-X25519-Ratchet encrypted [ECIES]_ garlic cloves.
|
||||
|
||||
This specification is for Delivery Instructions inside Garlic Cloves only.
|
||||
Note that "Delivery Instructions" are also used inside Tunnel Messages, where
|
||||
the format is significantly different. See the Tunnel Message documentation
|
||||
[TMDI]_ for details. Do NOT use the following specification for Tunnel Message
|
||||
Delivery Instructions!
|
||||
|
||||
Session key and delay are unused and never present, so the three
|
||||
possible lengths are 1 (LOCAL), 33 (ROUTER and DESTINATION), and 37 (TUNNEL) bytes.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
@ -684,8 +642,8 @@ Garlic_ 11
|
||||
TunnelData_ 18
|
||||
TunnelGateway_ 19
|
||||
Data_ 20
|
||||
TunnelBuild_ 21 deprecated
|
||||
TunnelBuildReply_ 22 deprecated
|
||||
TunnelBuild_ 21
|
||||
TunnelBuildReply_ 22
|
||||
VariableTunnelBuild_ 23 0.7.12
|
||||
VariableTunnelBuildReply_ 24 0.7.12
|
||||
ShortTunnelBuild_ 25 0.9.51
|
||||
@ -978,11 +936,6 @@ Contents
|
||||
Reply Encryption
|
||||
````````````````
|
||||
|
||||
NOTE: ElGamal routers are deprecated as of API 0.9.58.
|
||||
As the recommended minimum floodfill version to query is now 0.9.58,
|
||||
implementations need not implement encryption for ElGamal floodfill routers.
|
||||
ElGamal destinations are still supported.
|
||||
|
||||
Flag bit 4 is used in combination with bit 1 to determine the reply encryption mode.
|
||||
Flag bit 4 must only be set when sending to routers with version 0.9.46 or higher.
|
||||
See proposals 154 and 156 for details.
|
||||
@ -1011,7 +964,6 @@ reply_key, tags, and reply_tags are not present.
|
||||
ElG to ElG
|
||||
``````````````
|
||||
Supported as of 0.9.7.
|
||||
Deprecated as of 0.9.58.
|
||||
ElG destination sends a lookup to a ElG router.
|
||||
|
||||
Requester key generation:
|
||||
@ -1047,7 +999,6 @@ reply_key ::
|
||||
ECIES to ElG
|
||||
``````````````
|
||||
Supported as of 0.9.46.
|
||||
Deprecated as of 0.9.58.
|
||||
ECIES destination sends a lookup to a ElG router.
|
||||
The reply_key and reply_tags fields are redefined for an ECIES-encrypted reply.
|
||||
|
||||
@ -1245,21 +1196,9 @@ Notes
|
||||
|
||||
* The returned peer hashes are not necessarily closer to the key than the
|
||||
router being queried.
|
||||
For replies to regular lookups, this facilitates discovery of new floodfills
|
||||
and "backwards" searching (further-from-the-key) for robustness.
|
||||
|
||||
* The key for an exploration lookup is usually generated randomly.
|
||||
Therefore, the response's non-floodfill peer_hashes may be selected using an
|
||||
optimized algorithm, such as providing peers that are close to the key but not
|
||||
necessarily the closest in the entire local network database, to avoid an
|
||||
inefficient sort or search of the entire local database.
|
||||
Other strategies such as caching may also be appropriate.
|
||||
This is implementation-dependent.
|
||||
|
||||
* Typical number of hashes returned: 3
|
||||
|
||||
* Recommended maximum number of hashes to return: 16
|
||||
|
||||
* The lookup key, peer hashes, and from hash are "real" hashes, NOT routing
|
||||
keys.
|
||||
|
||||
@ -1306,18 +1245,11 @@ Notes
|
||||
"arrival time" is set to the current network-wide ID, which is 2 (i.e.
|
||||
0x0000000000000002).
|
||||
|
||||
|
||||
|
||||
.. _msg-Garlic:
|
||||
|
||||
Garlic
|
||||
------
|
||||
|
||||
Warning: This is the format used for ElGamal-encrypted garlic messages [CRYPTO-ELG]_.
|
||||
The format for ECIES-AEAD-X25519-Ratchet garlic messages and garlic cloves
|
||||
is significantly different; see [ECIES]_ for the specification.
|
||||
|
||||
|
||||
Description
|
||||
```````````
|
||||
Used to wrap multiple encrypted I2NP Messages
|
||||
@ -1529,8 +1461,6 @@ Notes
|
||||
TunnelBuild
|
||||
-----------
|
||||
|
||||
DEPRECATED, use VariableTunnelBuild_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
@ -1574,8 +1504,6 @@ Notes
|
||||
TunnelBuildReply
|
||||
----------------
|
||||
|
||||
DEPRECATED, use VariableTunnelBuildReply_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
@ -1710,7 +1638,7 @@ OutboundTunnelBuildReply
|
||||
|
||||
Description
|
||||
```````````
|
||||
Sent from the outbound endpoint of a new tunnel to the originator.
|
||||
Sent from the outbound gateway of a new tunnel to the originator.
|
||||
As of API version 0.9.51, for ECIES-X25519 routers only.
|
||||
|
||||
.. raw:: html
|
||||
|
@ -3,8 +3,8 @@ NTCP 2
|
||||
======
|
||||
.. meta::
|
||||
:category: Transports
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2022-12
|
||||
:accuratefor: 0.9.56
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -110,7 +110,7 @@ Alice Bob
|
||||
{% endhighlight %}
|
||||
|
||||
Using Noise terminology, the establishment and data sequence is as follows:
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
(Payload Security Properties)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -368,7 +368,7 @@ Noise content: Alice's ephemeral key X
|
||||
Noise payload: 16 byte option block
|
||||
Non-noise payload: Random padding
|
||||
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
(Payload Security Properties)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -574,10 +574,6 @@ Notes
|
||||
set a random timeout (range TBD) and then read a random number of bytes (range TBD),
|
||||
before closing the socket.
|
||||
|
||||
- Bob may do a fast MSB check for a valid key (X[31] & 0x80 == 0) before
|
||||
attempting decryption. If the high bit is set, implement probing resistance
|
||||
as for AEAD failures.
|
||||
|
||||
- DoS Mitigation: DH is a relatively expensive operation. As with the previous NTCP protocol,
|
||||
routers should take all necessary measures to prevent CPU or connection exhaustion.
|
||||
Place limits on maximum active connections and maximum connection setups in progress.
|
||||
@ -707,7 +703,7 @@ Noise content: Bob's ephemeral key Y
|
||||
Noise payload: 16 byte option block
|
||||
Non-noise payload: Random padding
|
||||
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
(Payload Security Properties)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -996,7 +992,7 @@ Noise content: Alice's static key
|
||||
Noise payload: Alice's RouterInfo and random padding
|
||||
Non-noise payload: none
|
||||
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
(Payload Security Properties)
|
||||
|
||||
|
||||
.. raw:: html
|
||||
@ -1271,7 +1267,7 @@ Types include date/time, I2NP message, options, termination, and padding.
|
||||
Note: Bob may, but is not required, to send his RouterInfo to Alice as
|
||||
his first message to Alice in the data phase.
|
||||
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
(Payload Security Properties)
|
||||
|
||||
|
||||
.. raw:: html
|
||||
@ -1387,14 +1383,6 @@ Raw contents
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Notes
|
||||
`````
|
||||
- As the receiver must get the entire frame to check the MAC,
|
||||
it is recommended that the sender limit frames to a few KB
|
||||
rather than maximizing the frame size.
|
||||
This will minimize latency at the receiver.
|
||||
|
||||
|
||||
|
||||
Unencrypted data
|
||||
````````````````
|
||||
|
@ -5,7 +5,7 @@ ECIES-X25519-AEAD-Ratchet
|
||||
:author: zzz, chisana, orignal
|
||||
:created: 2018-11-22
|
||||
:thread: http://zzz.i2p/topics/2639
|
||||
:lastupdated: 2025-03-05
|
||||
:lastupdated: 2020-11-12
|
||||
:status: Closed
|
||||
:target: 0.9.46
|
||||
:implementedin: 0.9.46
|
||||
@ -1109,7 +1109,7 @@ This is the "e" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
@ -1153,7 +1153,7 @@ This is the "ss" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -1173,7 +1173,7 @@ KDF for Payload Section (without Alice static key)
|
||||
Note that this is a Noise "N" pattern, but we use the same "IK" initializer
|
||||
as for bound sessions.
|
||||
|
||||
New Session messages can not be identified as containing Alice's static key or not
|
||||
New Session essages can not be identified as containing Alice's static key or not
|
||||
until the static key is decrypted and inspected to determine if it contains all zeros.
|
||||
Therefore, the receiver must use the "IK" state machine for all
|
||||
New Session messages.
|
||||
@ -1358,7 +1358,7 @@ KDF for Reply Key Section Encrypted Contents
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
||||
|
@ -5,7 +5,7 @@ ECIES Tunnels
|
||||
:author: chisana, zzz, orignal
|
||||
:created: 2019-07-04
|
||||
:thread: http://zzz.i2p/topics/2737
|
||||
:lastupdated: 2025-03-05
|
||||
:lastupdated: 2021-03-21
|
||||
:status: Closed
|
||||
:target: 0.9.48
|
||||
:implementedin: 0.9.48
|
||||
@ -700,7 +700,7 @@ Failing to use unique keys opens an attack vector for colluding hops to confirm
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
plaintext = 464 byte build request record
|
||||
ad = h
|
||||
|
@ -5,7 +5,7 @@ ECIES Routers
|
||||
:author: zzz, orignal
|
||||
:created: 2020-09-01
|
||||
:thread: http://zzz.i2p/topics/2950
|
||||
:lastupdated: 2025-03-05
|
||||
:lastupdated: 2021-07-31
|
||||
:status: Closed
|
||||
:target: 0.9.51
|
||||
|
||||
@ -331,7 +331,7 @@ This is the same as specified in [Tunnel-Creation-ECIES]_ and [Prop152]_ for tun
|
||||
//chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
plaintext = 464 byte build request record
|
||||
ad = h
|
||||
|
@ -5,8 +5,8 @@ SSU2
|
||||
:author: eyedeekay, orignal, zlatinb, zzz
|
||||
:created: 2021-09-12
|
||||
:thread: http://zzz.i2p/topics/2612
|
||||
:lastupdated: 2025-03-05
|
||||
:status: Closed
|
||||
:lastupdated: 2022-12-19
|
||||
:status: Open
|
||||
:target: 0.9.56
|
||||
|
||||
.. contents::
|
||||
@ -39,7 +39,7 @@ Connection Migration 0.9.55+ dev 0.9.56 2022-11
|
||||
Immediate ACK flag 0.9.55+ dev 0.9.56 2022-11
|
||||
Key Rotation 0.9.57 2023-02 0.9.58 2023-05
|
||||
Disable SSU 1 (i2pd) 0.9.56 2022-11
|
||||
Disable SSU 1 (Java I2P) 0.9.58 2023-05 0.9.61 2023-12
|
||||
Disable SSU 1 (Java I2P) 0.9.58 2023-05 0.9.59 2023-08
|
||||
========================== ===================== ====================
|
||||
|
||||
Basic Session includes the handshake and data phase.
|
||||
@ -2852,7 +2852,7 @@ Before header encryption:
|
||||
Short Header
|
||||
`````````````
|
||||
The short header is 16 bytes. It is used for Session Created and for Data messages.
|
||||
Unauthenticated messages such as Session Request, Retry, and Peer Test will
|
||||
Uauthenticated messages such as Session Request, Retry, and Peer Test will
|
||||
always use the long header.
|
||||
|
||||
16 bytes is required, because
|
||||
@ -3463,7 +3463,7 @@ KDF for Session Request
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -3764,7 +3764,7 @@ KDF for Session Created and Session Confirmed part 1
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -4044,7 +4044,7 @@ This is the "se" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -6717,7 +6717,7 @@ An additional packet count limit may be useful as well to prevent
|
||||
buffer overflow in the kernel or in middleboxes, implementation dependent,
|
||||
although this may add significant complexity.
|
||||
If per-session and/or total packet output is bandwidth-limited and/or paced,
|
||||
this may mitigate the need for packet count limiting.
|
||||
this may mitigate the need for packet count ilmiting.
|
||||
|
||||
|
||||
|
||||
|
@ -5,9 +5,9 @@ UDP Trackers
|
||||
:author: zzz
|
||||
:created: 2022-01-03
|
||||
:thread: http://zzz.i2p/topics/1634
|
||||
:lastupdated: 2025-06-09
|
||||
:lastupdated: 2022-12-19
|
||||
:status: Open
|
||||
:target: 0.9.68
|
||||
:target: 0.9.58
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -18,36 +18,6 @@ Overview
|
||||
This proposal is for implemention of UDP trackers in I2P.
|
||||
|
||||
|
||||
Change History
|
||||
--------------
|
||||
|
||||
A preliminary proposal for UDP trackers in I2P was posted on our bittorrent spec page [SPEC]_
|
||||
in May 2014; this predated our formal proposal process, and it was never implemented.
|
||||
This proposal was created in early 2022 and simplifies the 2014 version.
|
||||
|
||||
As this proposal relies on repliable datagrams, it was put on hold once we
|
||||
started working on the Datagram2 proposal [Prop163]_ in early 2023.
|
||||
That proposal was approved in April 2025.
|
||||
|
||||
The 2023 version of this proposal specified two modes, "compatibility" and "fast".
|
||||
Further analysis revealed that the fast mode would be insecure, and would also
|
||||
be inefficient for clients with a large number of torrents.
|
||||
Further, BiglyBT indicated a preference for compatibility mode.
|
||||
This mode will be easier to implement for any tracker or client supporting
|
||||
standard [BEP15]_.
|
||||
|
||||
While the compatibility mode is more complex to implement from-scratch
|
||||
on the client size, we do have preliminary code for it started in 2023.
|
||||
|
||||
Therefore, the current version here is further simplified to remove fast mode,
|
||||
and remove the term "compatibility". The current version switches to
|
||||
the new Datagram2 format, and adds references to the UDP announce extenstion
|
||||
protocol [BEP41]_.
|
||||
|
||||
Also, a connection ID lifetime field is added to the connect response,
|
||||
to extend the efficiency gains of this protocol.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
@ -57,6 +27,10 @@ we need to make trackers and announces more efficient so that trackers are not o
|
||||
Bittorrent proposed UDP trackers in BEP 15 [BEP15]_ in 2008, and the vast majority
|
||||
of trackers on clearnet are now UDP-only.
|
||||
|
||||
A preliminary proposal for UDP trackers in I2P was posted on our bittorrent spec page [SPEC]_
|
||||
in May 2014; this predated our formal proposal process, and it was never implemented.
|
||||
This proposal simplifies the 2014 version.
|
||||
|
||||
It is difficult to calculate the bandwidth savings of datagrams vs. streaming protocol.
|
||||
A repliable request is about the same size as a streaming SYN, but the payload
|
||||
is about 500 bytes smaller because the HTTP GET has a huge 600 byte
|
||||
@ -67,27 +41,19 @@ for a tracker's outbound traffic.
|
||||
Additionally, there should be implementation-specific memory reductions,
|
||||
as datagrams require much less in-memory state than a streaming connection.
|
||||
|
||||
Post-Quantum encryption and signatures as envisioned in [Prop169]_ will substantially
|
||||
increase the overhead of encrypted and signed structures, including destinations,
|
||||
leasesets, streaming SYN and SYN ACK. It is important to minimize this
|
||||
overhead where possible before PQ crypto is adopted in I2P.
|
||||
|
||||
|
||||
Design
|
||||
============
|
||||
|
||||
This proposal uses repliable datagram2, repliable datagram3, and raw datagrams,
|
||||
This proposal uses both repliable and raw datagrams,
|
||||
as defined in [DATAGRAMS]_.
|
||||
Datagram2 and Datagram3 are new variants of repliable datagrams,
|
||||
defined in Proposal 163 [Prop163]_.
|
||||
Datagram2 adds replay resistance and offline signature support.
|
||||
Datagram3 is smaller than the old datagram format, but without authentication.
|
||||
|
||||
|
||||
BEP 15
|
||||
-------
|
||||
|
||||
For reference, the message flow defined in [BEP15]_ is as follows:
|
||||
The message flow in [BEP15]_ is as follows:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -103,127 +69,66 @@ Client Tracker
|
||||
|
||||
The connect phase is required to prevent IP address spoofing.
|
||||
The tracker returns a connection ID that the client uses in subsequent announces.
|
||||
This connection ID expires by default in one minute at the client, and in two minutes at the tracker.
|
||||
This connection ID expires in one minute at the client, and in two minutes at the tracker.
|
||||
This is not necessary in I2P because of repliable datagrams.
|
||||
|
||||
I2P will use the same message flow as BEP 15,
|
||||
We propose two mechanisms for I2P, compatibility mode and fast mode.
|
||||
|
||||
|
||||
Compatibility Mode
|
||||
-------------------------
|
||||
|
||||
In compatibility mode, we keep the same message flow as BEP 15,
|
||||
for ease of adoption in existing UDP-capable client code bases:
|
||||
for efficiency, and for security reasons discussed below:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Client Tracker
|
||||
Connect Req. -------------> (Repliable Datagram2)
|
||||
Connect Req. -------------> (Repliable)
|
||||
<-------------- Connect Resp. (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
Announce Req. -------------> (Raw)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
Announce Req. -------------> (Raw)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
...
|
||||
{% endhighlight %}
|
||||
|
||||
This potentially provides a large bandwidth savings over
|
||||
streaming (TCP) announces.
|
||||
While the Datagram2 is about the same size as a streaming SYN,
|
||||
the raw response is much smaller than the streaming SYN ACK.
|
||||
Subsequent requests use Datagram3, and the subsequent responses are raw.
|
||||
|
||||
The announce requests are Datagram3 so that the tracker need not
|
||||
maintain a large mapping table of connection IDs to announce destination or hash.
|
||||
Instead, the tracker may generate connection IDs cryptographically
|
||||
from the sender hash, the current timestamp (based on some interval),
|
||||
and a secret value.
|
||||
When an announce request is received, the tracker validates the
|
||||
connection ID, and then uses the
|
||||
Datagram3 sender hash as the send target.
|
||||
This mode is also useful if the client plans to send multiple announces
|
||||
within one minute to a single tracker, as only the connect
|
||||
message must be repliable.
|
||||
|
||||
|
||||
Tracker/Client support
|
||||
----------------------
|
||||
|
||||
For an integrated application (router and client in one process, for example i2psnark, and the ZzzOT Java plugin),
|
||||
or for an I2CP-based application (for example BiglyBT),
|
||||
it should be straightforward to implement and route the streaming and datagram traffic separately.
|
||||
ZzzOT and i2psnark are expected to be the first tracker and client to implement this proposal.
|
||||
|
||||
Non-integrated trackers and clients are discussed below.
|
||||
|
||||
|
||||
Trackers
|
||||
````````
|
||||
|
||||
There are four known I2P tracker implementations:
|
||||
|
||||
- zzzot, an integrated Java router plugin, running at opentracker.dg2.i2p and several others
|
||||
- tracker2.postman.i2p, running presumably behind a Java router and HTTP Server tunnel
|
||||
- The old C opentracker, ported by zzz, with UDP support commented out
|
||||
- The new C opentracker, ported by r4sas, running at opentracker.r4sas.i2p and possibly others,
|
||||
running presumably behind a i2pd router and HTTP Server tunnel
|
||||
|
||||
For an external tracker application that currently uses an HTTP server tunnel to receive
|
||||
announce requests, the implementation could be quite difficult.
|
||||
A specialized tunnel could be developed to translate datagrams to local HTTP requests/responses.
|
||||
Or, a specialized tunnel that handles both HTTP requests and datagrams could be designed
|
||||
that would forward the datagrams to the external process.
|
||||
These design decisions will depend heavily on the specific router and tracker implementations,
|
||||
and are outside the scope of this proposal.
|
||||
|
||||
|
||||
Clients
|
||||
```````
|
||||
External SAM-based torrent clients such as qbittorrent and other libtorrent-based clients
|
||||
would require SAM v3.3 [SAMv3]_ which is not supported by i2pd.
|
||||
This is also required for DHT support, and is complex enough that no known
|
||||
SAM torrent client has implemented it.
|
||||
No SAM-based implementations of this proposal are expected soon.
|
||||
|
||||
|
||||
Connection Lifetime
|
||||
-------------------
|
||||
|
||||
[BEP15]_ specifies that the connection ID expires in one minute at the client, and in two minutes at the tracker.
|
||||
It is not configurable.
|
||||
That limits the potential efficiency gains, unless
|
||||
clients batched announces to do all of them within a one-minute window.
|
||||
i2psnark does not currently batch announces; it spreads them out, to avoid bursts of traffic.
|
||||
Power users are reported to be running thousands of torrents at once,
|
||||
and bursting that many announces into one minute is not realistic.
|
||||
|
||||
Here, we propose to extend the connect response to add an optional connection lifetime field.
|
||||
The default, if not present, is one minute. Otherwise, the lifetime specified
|
||||
in seconds, shall be used by the client, and the tracker will maintain the
|
||||
connection ID for one minute more.
|
||||
|
||||
|
||||
Compatibility with BEP 15
|
||||
I2P Fast Mode
|
||||
-------------------------
|
||||
|
||||
This design maintains compatibility with [BEP15]_ as much as possible
|
||||
to limit changes required in existing clients and trackers.
|
||||
In fast mode, we omit the connect phase, as it is not required to prevent address spoofing.
|
||||
This significantly simplifies the client-side implementation.
|
||||
|
||||
The only required change is the format of peer info in the announce response.
|
||||
The addition of the lifetime field in the connect response is not required
|
||||
but is strongly recommended for efficiency, as explained above.
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Client Tracker
|
||||
Announce Req. -------------> (Repliable)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
{% endhighlight %}
|
||||
|
||||
This mode omits a round-trip, but requires every announce request to be repliable.
|
||||
|
||||
|
||||
Security Analysis
|
||||
------------------
|
||||
|
||||
An important goal of a UDP announce protocol is to prevent address spoofing.
|
||||
The client must actually exist and bundle a real leaseset.
|
||||
The primary goal of an announce protocol is to impose a cost on address spoofing.
|
||||
In compatibility mode, the client must actually exist and bundle a real leaseset.
|
||||
It must have inbound tunnels to receive the Connect Response.
|
||||
These tunnels could be zero-hop and built instantly, but that would
|
||||
expose the creator.
|
||||
This protocol accomplishes that goal.
|
||||
|
||||
|
||||
|
||||
Issues
|
||||
------
|
||||
|
||||
- This proposal does not support blinded destinations,
|
||||
but may be extended to do so. See below.
|
||||
However, in fast mode, the destination and leaseset could be fake.
|
||||
Multiple fake destinations and leasesets can be rapidly generated without
|
||||
actually building tunnels. The Announce Request messages could then be sent out
|
||||
any tunnel.
|
||||
|
||||
|
||||
|
||||
@ -231,57 +136,15 @@ Issues
|
||||
Specification
|
||||
=============
|
||||
|
||||
Protocols and Ports
|
||||
-------------------
|
||||
|
||||
Repliable Datagram2 uses I2CP protocol 19;
|
||||
repliable Datagram3 uses I2CP protocol 20;
|
||||
raw datagrams use I2CP protocol 18.
|
||||
Requests may be Datagram2 or Datagram3. Responses are always raw.
|
||||
The older repliable datagram ("Datagram1") format using I2CP protocol 17
|
||||
must NOT be used for requests or replies; these must be dropped if received
|
||||
on the request/reply ports. Note that Datagram1 protocol 17
|
||||
is still used for the DHT protocol.
|
||||
|
||||
Requests use the I2CP "to port" from the announce URL; see below.
|
||||
The request "from port" is chosen by the client, but should be nonzero,
|
||||
and a different port from those used by DHT, so that responses
|
||||
may be easily classified.
|
||||
Trackers should reject requests received on the wrong port.
|
||||
|
||||
Responses use the I2CP "to port" from the request.
|
||||
The request "from port" is the "to port" from the request.
|
||||
|
||||
|
||||
Announce URL
|
||||
------------
|
||||
|
||||
The announce URL format is not specified in [BEP15]_,
|
||||
but as in clearnet, UDP announce URLs are of the form "udp://host:port/path".
|
||||
The path is ignored and may be empty, but is typically "/announce" on clearnet.
|
||||
The :port part should always be present, however,
|
||||
if the ":port" part is omitted, use a default I2CP port of 6969,
|
||||
as that is the common port on clearnet.
|
||||
There may also be cgi parameters &a=b&c=d appended,
|
||||
those may be processed and provided in the announce request, see [BEP41]_.
|
||||
If there are no parameters or path, the trailing / may also be omitted,
|
||||
as implied in [BEP41]_.
|
||||
|
||||
|
||||
Datagram Formats
|
||||
----------------
|
||||
|
||||
All values are send in network byte order (big endian).
|
||||
Do not expect packets to be exactly of a certain size.
|
||||
Future extensions could increase the size of packets.
|
||||
|
||||
Repliable datagrams use I2CP protocol 17; raw datagrams use I2CP protocol 18.
|
||||
Requests may be repliable or raw. Responses are always raw.
|
||||
|
||||
|
||||
Connect Request
|
||||
```````````````
|
||||
-----------------
|
||||
|
||||
Client to tracker.
|
||||
16 bytes. Must be repliable Datagram2. Same as in [BEP15]_. No changes.
|
||||
16 bytes. Must be repliable. Same as in [BEP15]_.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
@ -296,10 +159,10 @@ Offset Size Name Value
|
||||
|
||||
|
||||
Connect Response
|
||||
````````````````
|
||||
-----------------
|
||||
|
||||
Tracker to client.
|
||||
16 or 18 bytes. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
16 bytes. Must be raw. Same as in [BEP15]_.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
@ -309,64 +172,68 @@ Offset Size Name Value
|
||||
0 32-bit integer action 0 // connect
|
||||
4 32-bit integer transaction_id
|
||||
8 64-bit integer connection_id
|
||||
16 16-bit integer lifetime optional // Change from BEP 15
|
||||
{% endhighlight %}
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
|
||||
The lifetime field is optional and indicates the connection_id client lifetime in seconds.
|
||||
The default is 60, and the minimum if specified is 60.
|
||||
The maximum is 65535 or about 18 hours.
|
||||
The tracker should maintain the connection_id for 60 seconds more than the client lifetime.
|
||||
|
||||
|
||||
|
||||
Announce Request
|
||||
````````````````
|
||||
-----------------
|
||||
|
||||
Client to tracker.
|
||||
98 bytes minimum. Must be repliable Datagram3. Same as in [BEP15]_ except as noted below.
|
||||
98 bytes. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
The connection_id is as received in the connect response.
|
||||
If preceded by a connect request/response, must be raw,
|
||||
with the connection_id received in the connect response.
|
||||
|
||||
|
||||
If NOT preceded by a connect request/response, must be repliable,
|
||||
and the connection_id is ignored.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Offset Size Name Value
|
||||
0 64-bit integer connection_id
|
||||
8 32-bit integer action 1 // announce
|
||||
8 32-bit integer action 1 // announce
|
||||
12 32-bit integer transaction_id
|
||||
16 20-byte string info_hash
|
||||
36 20-byte string peer_id
|
||||
56 64-bit integer downloaded
|
||||
64 64-bit integer left
|
||||
72 64-bit integer uploaded
|
||||
80 32-bit integer event 0 // 0: none; 1: completed; 2: started; 3: stopped
|
||||
84 32-bit integer IP address 0 // default
|
||||
80 32-bit integer event 0 // 0: none; 1: completed; 2: started; 3: stopped
|
||||
84 32-bit integer IP address 0 // default
|
||||
88 32-bit integer key
|
||||
92 32-bit integer num_want -1 // default
|
||||
92 32-bit integer num_want -1 // default
|
||||
96 16-bit integer port
|
||||
98 varies options optional // As specified in BEP 41
|
||||
98 TBD additional data TBD
|
||||
{% endhighlight %}
|
||||
|
||||
Changes from [BEP15]_:
|
||||
|
||||
- connection_id is ignored if repliable
|
||||
- IP address is ignored
|
||||
- key is ignored
|
||||
- port is probably ignored
|
||||
- The options section, if present, is as defined in [BEP41]_
|
||||
- Explicitly indidate that the protocol is extensible,
|
||||
with possible additional data starting at port 98.
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
Do not use the port from the announce request.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Announce Response
|
||||
`````````````````
|
||||
-----------------
|
||||
|
||||
Tracker to client.
|
||||
20 bytes minimum. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
20+ bytes. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
|
||||
|
||||
@ -379,68 +246,74 @@ Offset Size Name Value
|
||||
8 32-bit integer interval
|
||||
12 32-bit integer leechers
|
||||
16 32-bit integer seeders
|
||||
20 32 * n 32-byte hash binary hashes // Change from BEP 15
|
||||
... // Change from BEP 15
|
||||
20 16-bit integer count of hashes to follow
|
||||
22 32 * n 32-byte hash binary hashes
|
||||
...
|
||||
22 + 32 * n TBD additional data TBD
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Changes from [BEP15]_:
|
||||
|
||||
- Add a hash count before the hashes, so that the response format
|
||||
is extensible with additional data after the hashes.
|
||||
- Instead of 6-byte IPv4+port or 18-byte IPv6+port, we return
|
||||
a multiple of 32-byte "compact responses" with the SHA-256 binary peer hashes.
|
||||
As with TCP compact responses, we do not include a port.
|
||||
- Explicitly indidate that the protocol is extensible,
|
||||
with possible additional data starting after the hashes
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
Do not use the port from the announce request.
|
||||
|
||||
I2P datagrams have a very large maximum size of about 64 KB;
|
||||
I2P datagrams have a very large maximum size of about 16 KB;
|
||||
however, for reliable delivery, datagrams larger than 4 KB should be avoided.
|
||||
For bandwidth efficiency, trackers should probably limit the maximum peers
|
||||
to about 50, which corresponds to about a 1600 byte packet before overhead
|
||||
at various layers, and should be within a two-tunnel-message payload limit
|
||||
after fragmentation.
|
||||
|
||||
As in BEP 15, there is no count included of the number of peer addresses
|
||||
(IP/port for BEP 15, hashes here) to follow.
|
||||
While not contemplated in BEP 15, an end-of-peers marker
|
||||
of all zeros could be defined to indicate that the peer info is complete
|
||||
and some extension data follows.
|
||||
|
||||
So that extension is possible in the future, clients should ignore
|
||||
a 32-byte all-zeros hash, and any data that follows.
|
||||
Trackers should reject announces from an all-zeros hash,
|
||||
although that hash is already banned by Java routers.
|
||||
to about 50.
|
||||
|
||||
|
||||
Scrape
|
||||
``````
|
||||
----------
|
||||
|
||||
Scrape request/response from [BEP15]_ is not required by this proposal,
|
||||
but may be implemented if desired, no changes required.
|
||||
The client must acquire a connection ID first.
|
||||
The scrape request is always repliable Datagram3.
|
||||
The scrape response is always raw.
|
||||
|
||||
The scrape request is always repliable (unless there is a previous connect request/response)
|
||||
and the scrape response is always raw.
|
||||
|
||||
|
||||
Error Response
|
||||
``````````````
|
||||
------------------
|
||||
|
||||
Tracker to client.
|
||||
8 bytes minimum (if the message is empty).
|
||||
Must be raw. Same as in [BEP15]_. No changes.
|
||||
Error response from [BEP15]_ is not required by this proposal,
|
||||
but may be implemented if desired, no changes required.
|
||||
The error response is always raw.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Announce URL
|
||||
------------
|
||||
|
||||
Offset Size Name Value
|
||||
0 32-bit integer action 3 // error
|
||||
4 32-bit integer transaction_id
|
||||
8 string message
|
||||
As in clearnet, UDP announce URLs are of the form "udp://host:port/path".
|
||||
The path is ignored and may be empty.
|
||||
If the ":port" part is omitted, use an I2CP port of 0.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Issues
|
||||
=======
|
||||
|
||||
- Repliable datagrams do not support offline signatures.
|
||||
That requires a separate proposal.
|
||||
- This proposal does not support blinded destinations,
|
||||
but may be extended to do so. See below.
|
||||
- This proposal offers two modes at the client's option.
|
||||
An existing clearnet tracker such as "opentracker" would require more modifications
|
||||
to support the fast mode. There is no way in the announce URL to indicate
|
||||
support for only one mode.
|
||||
- Compatibility mode may not be necessary, pending feedback from BiglyBT and
|
||||
other developers. However, it would still save a lot of bandwidth
|
||||
if it is used for several announces within a minute.
|
||||
Repliable announces are about 450 bytes larger than raw announces.
|
||||
|
||||
|
||||
Extensions
|
||||
=============
|
||||
@ -448,39 +321,36 @@ Extensions
|
||||
Extension bits or a version field are not included.
|
||||
Clients and trackers should not assume packets to be of a certain size.
|
||||
This way, additional fields can be added without breaking compatibility.
|
||||
The extensions format defined in [BEP41]_ is recommended if required.
|
||||
|
||||
The connect response is modified to add an optional connection ID lifetime.
|
||||
The announce response is modified to include a count of peer hashes,
|
||||
so that the response may be easily extended with additional information.
|
||||
|
||||
If blinded destination support is required, we can either add the
|
||||
blinded 35-byte address to the end of the announce request,
|
||||
or request blinded hashes in the responses,
|
||||
using the [BEP41]_ format (paramters TBD).
|
||||
The set of blinded 35-byte peer addresses could be added to the end of the announce reply,
|
||||
after an all-zeros 32-byte hash.
|
||||
blinded 35-byte address to the end of the announce request, or define a new blinded announce request message.
|
||||
The set of blinded 35-byte peer addresses could be added to the end of the announce reply.
|
||||
|
||||
|
||||
|
||||
Implementation guidelines
|
||||
==========================
|
||||
|
||||
See the design section above for a discussion of the challenges for
|
||||
non-integrated, non-I2CP clients and trackers.
|
||||
|
||||
|
||||
Clients
|
||||
--------
|
||||
|
||||
For a given tracker hostname, a client should prefer UDP over HTTP URLs,
|
||||
and should not announce to both.
|
||||
|
||||
Clients wihout existing BEP 15 support should implement
|
||||
fast mode only, as it is much simpler.
|
||||
Clients with existing BEP 15 support should require only small modifications.
|
||||
Evaluate both fast and compatibility modes and choose
|
||||
whatever is best for the existing code base.
|
||||
|
||||
If a client support DHT or other datagram protocols, it should probably
|
||||
select a different port as the request "from port" so that the replies
|
||||
come back to that port and are not mixed up with DHT messages.
|
||||
The client only receives raw datagrams as replies.
|
||||
Trackers will never send a repliable datagram2 to the client.
|
||||
Trackers will never send a repliable datagram to the client.
|
||||
|
||||
Clients with a default list of opentrackers should update the list to
|
||||
add UDP URLs after the known opentrackers are known to support UDP.
|
||||
@ -490,32 +360,27 @@ Retransmissions, if implemented, should use an initial timeout
|
||||
of at least 15 seconds, and double the timeout for each retransmission
|
||||
(exponential backoff).
|
||||
|
||||
Clients must back off after receiving an error response.
|
||||
|
||||
|
||||
Trackers
|
||||
---------
|
||||
|
||||
Trackers must implement both compatibility mode and fast mode.
|
||||
Trackers with existing BEP 15 support should require only small modifications.
|
||||
This proposal differs from the 2014 proposal, in that the tracker
|
||||
must support reception of repliable datagram2 and datagram3 on the same port.
|
||||
must support reception of repliable and raw datagrams on the same port.
|
||||
|
||||
To minimize tracker resource requirements,
|
||||
this protocol is designed to eliminate any requirement that the tracker
|
||||
store mappings of client hashes to connection IDs for later validation.
|
||||
This is possible because the announce request packet is a repliable
|
||||
Datagram3 packet, so it contains the sender's hash.
|
||||
For an integrated application (router and client in one process, for example the ZzzOT Java plugin),
|
||||
it should be straightforward to implement and route the streaming and datagram traffic separately.
|
||||
|
||||
For an external tracker application that currently uses an HTTP server tunnel to receive
|
||||
announce requests, the implementation could be quite difficult.
|
||||
A specialized tunnel could be developed to translate datagrams to local HTTP requests/responses.
|
||||
Or, a specialized tunnel that handles both HTTP requests and datagrams could be designed
|
||||
that would forward the datagrams to the external process.
|
||||
These design decisions will depend heavily on the specific router and tracker implementations,
|
||||
and are outside the scope of this proposal.
|
||||
|
||||
A recommended implementation is:
|
||||
|
||||
- Define the current epoch as the current time with a resolution of the connection lifetime,
|
||||
``epoch = now / lifetime``.
|
||||
- Define a cryptographic hash function ``H(secret, clienthash, epoch)`` which generates
|
||||
an 8 byte output.
|
||||
- Generate the random constant secret used for all connections.
|
||||
- For connect responses, generate ``connection_id = H(secret, clienthash, epoch)``
|
||||
- For announce requests, validate the received connection ID in the current epoch by verifying
|
||||
``connection_id == H(secret, clienthash, epoch) || connection_id == H(secret, clienthash, epoch - 1)``
|
||||
|
||||
|
||||
Migration
|
||||
@ -546,20 +411,8 @@ References
|
||||
.. [BEP15]
|
||||
http://www.bittorrent.org/beps/bep_0015.html
|
||||
|
||||
.. [BEP41]
|
||||
http://www.bittorrent.org/beps/bep_0041.html
|
||||
|
||||
.. [DATAGRAMS]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
.. [Prop163]
|
||||
{{ proposal_url('163') }}
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
||||
|
||||
.. [SAMv3]
|
||||
{{ site_url('docs/api/samv3') }}
|
||||
|
||||
.. [SPEC]
|
||||
{{ site_url('docs/applications/bittorrent', True) }}
|
||||
|
@ -2,395 +2,135 @@
|
||||
Datagram2 Protocol
|
||||
===================================
|
||||
.. meta::
|
||||
:author: zzz, orignal, drzed, eyedeekay
|
||||
:author: zzz
|
||||
:created: 2023-01-24
|
||||
:thread: http://zzz.i2p/topics/3540
|
||||
:lastupdated: 2025-04-16
|
||||
:status: Closed
|
||||
:target: 0.9.67
|
||||
:lastupdated: 2023-01-24
|
||||
:status: Open
|
||||
:target: 0.9.60
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
Approved at review 2025-04-15.
|
||||
Changes incorporated into specs.
|
||||
Not yet supported in any known implenentations.
|
||||
Target implementation for Java I2P is API 0.9.67.
|
||||
Check implementation documentation for status.
|
||||
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Pulled out from [Prop123]_ as a separate proposal.
|
||||
Pulled out from [Prop123]_ as a separate proposal. Copied from [Prop123]_:
|
||||
|
||||
Offline signatures cannot be verified in the repliable datagram processing.
|
||||
Needs a flag to indicate offline signed but there's no place to put a flag.
|
||||
|
||||
Will require a completely new I2CP protocol number and format,
|
||||
Will require a completely new protocol number and format.
|
||||
to be added to the [DATAGRAMS]_ specification.
|
||||
Let's call it "Datagram2".
|
||||
|
||||
|
||||
Goals
|
||||
=====
|
||||
|
||||
- Add support for offline signatures
|
||||
- Add replay resistance
|
||||
- Add flavor without signatures
|
||||
- Add flags and options fields for extensibility
|
||||
|
||||
|
||||
Non-Goals
|
||||
=========
|
||||
|
||||
Full end-to-end protocol support for congestion control, etc.
|
||||
That would be build on top of, or an alternative to, Datagram2, which is a low-level protocol.
|
||||
It would not make sense to design a high-performance protocol solely atop
|
||||
Datagram2, because of the from field and signature overhead.
|
||||
Any such protocol should do an initial handshake with Datagram2 and then
|
||||
switch to RAW datagrams.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
Left over from LS2 work otherwise completed in 2019.
|
||||
|
||||
The first application to use Datagram2 is expected to be
|
||||
bittorrent UDP announces, as implemented in i2psnark and zzzot,
|
||||
see [Prop160]_.
|
||||
|
||||
|
||||
Repliable Datagram Spec
|
||||
========================
|
||||
|
||||
For reference,
|
||||
following is a review of the specification for repliable datagrams,
|
||||
copied from [Datagrams]_.
|
||||
The standard I2CP protocol number for repliable datagrams is PROTO_DATAGRAM (17).
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' -%}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| from |
|
||||
+ +
|
||||
| |
|
||||
~ ~
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| signature |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| payload...
|
||||
+----+----+----+----//
|
||||
|
||||
|
||||
from :: a `Destination`
|
||||
length: 387+ bytes
|
||||
The originator and signer of the datagram
|
||||
|
||||
signature :: a `Signature`
|
||||
Signature type must match the signing public key type of $from
|
||||
length: 40+ bytes, as implied by the Signature type.
|
||||
For the default DSA_SHA1 key type:
|
||||
The DSA `Signature` of the SHA-256 hash of the payload.
|
||||
For other key types:
|
||||
The `Signature` of the payload.
|
||||
The signature may be verified by the signing public key of $from
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 31.5 KB (see notes)
|
||||
|
||||
Total length: Payload length + 423+
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
- Define new protocol 19 - Repliable datagram with options.
|
||||
- Define new protocol 20 - Repliable datagram without signature.
|
||||
- Add flags field for offline signatures and future expansion
|
||||
- Move signature after the payload for easier processing
|
||||
- New signature specification different from repliable datagram or streaming, so that
|
||||
signature verification will fail if interpreted as repliable datagram or streaming.
|
||||
This is accomplished by moving the signature after the payload,
|
||||
and by including the destination hash in the signature function.
|
||||
- Add replay prevention for datagrams, as was done in [Prop164]_ for streaming.
|
||||
- Add section for arbitrary options
|
||||
- Reuse offline signature format from [Common]_ and [Streaming]_.
|
||||
- Offline signature section must be before the variable-length
|
||||
payload and signature sections, as it specifies the length
|
||||
of the signature.
|
||||
Define new protocol 19 - Repliable datagram with options.
|
||||
|
||||
New signature specification.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Protocol
|
||||
--------
|
||||
|
||||
The new I2CP protocol number for Datagram2 is 19.
|
||||
Add it as PROTO_DATAGRAM2 to [I2CP]_.
|
||||
|
||||
The new I2CP protocol number for Datagram3 is 20.
|
||||
Add it as PROTO_DATAGRAM2 to [I2CP]_.
|
||||
|
||||
|
||||
Datagram2 Format
|
||||
----------------
|
||||
|
||||
Add Datagram2 to [DATAGRAMS]_ as follows:
|
||||
|
||||
|
||||
Format
|
||||
-------
|
||||
|
||||
Preliminary, copied from [Prop123]_:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' -%}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ from ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| flags | options (optional) |
|
||||
+----+----+ +
|
||||
~ ~
|
||||
~ ~
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ offline_signature (optional) ~
|
||||
~ expires, sigtype, pubkey, offsig ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ payload ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ signature ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
{% highlight %}
|
||||
From (387+ bytes)
|
||||
|
||||
from :: a `Destination`
|
||||
length: 387+ bytes
|
||||
The originator and (unless offline signed) signer of the datagram
|
||||
Flags (2 bytes)
|
||||
Bit order: 15 14 ... 3 2 1 0
|
||||
Bit 0: If 0, no offline keys; if 1, offline keys
|
||||
Bits 1-15: set to 0 for compatibility with future uses
|
||||
If flag indicates offline keys, the offline signature section:
|
||||
|
||||
flags :: (2 bytes)
|
||||
Bit order: 15 14 ... 3 2 1 0
|
||||
Bits 3-0: Version: 0x02 (0 0 1 0)
|
||||
Bit 4: If 0, no options; if 1, options mapping is included
|
||||
Bit 5: If 0, no offline sig; if 1, offline signed
|
||||
Bits 15-6: unused, set to 0 for compatibility with future uses
|
||||
Expires timestamp
|
||||
(4 bytes, big endian, seconds since epoch, rolls over in 2106)
|
||||
|
||||
options :: (2+ bytes if present)
|
||||
If flag indicates options are present, a `Mapping`
|
||||
containing arbitrary text options
|
||||
Transient sig type (2 bytes, big endian)
|
||||
|
||||
offline_signature ::
|
||||
If flag indicates offline keys, the offline signature section,
|
||||
as specified in the Common Structures Specification,
|
||||
with the following 4 fields. Length: varies by online and offline
|
||||
sig types, typically 102 bytes for Ed25519
|
||||
This section can, and should, be generated offline.
|
||||
Transient signing public key (length as implied by sig type)
|
||||
|
||||
expires :: Expires timestamp
|
||||
(4 bytes, big endian, seconds since epoch, rolls over in 2106)
|
||||
Signature of expires timestamp, transient sig type,
|
||||
and public key, by the destination public key,
|
||||
length as implied by destination public key sig type.
|
||||
This section can, and should, be generated offline.
|
||||
|
||||
sigtype :: Transient sig type (2 bytes, big endian)
|
||||
|
||||
pubkey :: Transient signing public key (length as implied by sig type),
|
||||
typically 32 bytes for Ed25519 sig type.
|
||||
|
||||
offsig :: a `Signature`
|
||||
Signature of expires timestamp, transient sig type,
|
||||
and public key, by the destination public key,
|
||||
length: 40+ bytes, as implied by the Signature type, typically
|
||||
64 bytes for Ed25519 sig type.
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 61 KB (see notes)
|
||||
|
||||
signature :: a `Signature`
|
||||
Signature type must match the signing public key type of $from
|
||||
(if no offline signature) or the transient sigtype
|
||||
(if offline signed)
|
||||
length: 40+ bytes, as implied by the Signature type, typically
|
||||
64 bytes for Ed25519 sig type.
|
||||
The `Signature` of the payload and other fields as specified below.
|
||||
The signature is verified by the signing public key of $from
|
||||
(if no offline signature) or the transient pubkey
|
||||
(if offline signed)
|
||||
Payload
|
||||
|
||||
Signature
|
||||
{% endhighlight %}
|
||||
|
||||
Total length: minimum 433 + payload length;
|
||||
typical length for X25519 senders and without offline signatures:
|
||||
457 + payload length.
|
||||
Note that the message will typically be compressed with gzip at the I2CP layer,
|
||||
which will result in significant savings if the from destination is compressible.
|
||||
|
||||
Note: The offline signature format is the same as in the Common Structures spec [Common]_ and [Streaming]_.
|
||||
|
||||
Signatures
|
||||
----------
|
||||
|
||||
The signature is over the following fields.
|
||||
TBD
|
||||
|
||||
- Prelude: The 32-byte hash of the target destination (not included in the datagram)
|
||||
- flags
|
||||
- options (if present)
|
||||
- offline_signature (if present)
|
||||
- payload
|
||||
Prelude: "DatagramProtocol" ?
|
||||
|
||||
In repliable datagram, for the DSA_SHA1 key type, the signature was over the
|
||||
SHA-256 hash of the payload, not the payload itself; here, the signature is
|
||||
always over the fields above (NOT the hash), regardless of key type.
|
||||
|
||||
|
||||
ToHash Verification
|
||||
-------------------
|
||||
|
||||
Receivers must verify the signature (using their destination hash)
|
||||
and discard the datagram on failure, for replay prevention.
|
||||
|
||||
|
||||
Datagram3 Format
|
||||
----------------
|
||||
|
||||
Add Datagram3 to [DATAGRAMS]_ as follows:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' -%}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ fromhash ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| flags | options (optional) |
|
||||
+----+----+ +
|
||||
~ ~
|
||||
~ ~
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
~ payload ~
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
fromhash :: a `Hash`
|
||||
length: 32 bytes
|
||||
The originator of the datagram
|
||||
|
||||
flags :: (2 bytes)
|
||||
Bit order: 15 14 ... 3 2 1 0
|
||||
Bits 3-0: Version: 0x03 (0 0 1 1)
|
||||
Bit 4: If 0, no options; if 1, options mapping is included
|
||||
Bits 15-5: unused, set to 0 for compatibility with future uses
|
||||
|
||||
options :: (2+ bytes if present)
|
||||
If flag indicates options are present, a `Mapping`
|
||||
containing arbitrary text options
|
||||
|
||||
payload :: The data
|
||||
Length: 0 to about 61 KB (see notes)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Total length: minimum 34 + payload length.
|
||||
|
||||
|
||||
|
||||
SAM
|
||||
---
|
||||
|
||||
Add STYLE=DATAGRAM2 and STYLE=DATAGRAM3 to the SAMv3 specification.
|
||||
Update the information on offline signatures.
|
||||
|
||||
|
||||
Overhead
|
||||
--------
|
||||
|
||||
This design adds 2 bytes of overhead to repliable datagrams for flags.
|
||||
This is acceptable.
|
||||
Add STYLE=DATAGRAM2
|
||||
|
||||
|
||||
|
||||
Security Analysis
|
||||
=================
|
||||
|
||||
Including the target hash in the signature should be effective at preventing replay attacks.
|
||||
|
||||
The Datagram3 format lacks signatures, so the sender cannot be verified,
|
||||
and replay attacks are possible. Any required validation must be done at the application layer,
|
||||
or by the router at the ratchet layer.
|
||||
|
||||
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
- The practical length is limited by lower layers of protocols - the tunnel
|
||||
message spec [TUNMSG]_ limits messages to about 61.2 KB and the transports
|
||||
[TRANSPORT]_ currently limit messages to about 64 KB, so the data length here
|
||||
is limited to about 61 KB.
|
||||
- See important notes about the reliability of large datagrams [API]_. For
|
||||
best results, limit the payload to about 10 KB or less.
|
||||
|
||||
|
||||
|
||||
|
||||
Compatibility
|
||||
===============
|
||||
|
||||
None. Applications must be rewritten to route Datagram2 I2CP messages
|
||||
based on protocol and/or port.
|
||||
Datagram2 messages that are misrouted and interpreted as
|
||||
Repliable datagram or streaming messages will fail based on signature, format, or both.
|
||||
|
||||
None
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Each UDP application must separately detect support and migrate.
|
||||
The most prominent UDP application is bittorrent.
|
||||
|
||||
Bittorrent
|
||||
----------
|
||||
|
||||
Bittorrent DHT: Needs extension flag probably,
|
||||
e.g. i2p_dg2, coordinate with BiglyBT
|
||||
|
||||
Bittorrent UDP Announces [Prop160]_: Design in from the beginning.
|
||||
Coordindate with BiglyBT, i2psnark, zzzot
|
||||
Bittorrent UDP Announces [Prop160]_: Design in from the beginning?
|
||||
Coorindate with BiglyBT, i2psnark, zzzot
|
||||
|
||||
Others
|
||||
------
|
||||
Bote: Unlikely
|
||||
|
||||
Bote: Unlikely to migrate, not actively maintained
|
||||
|
||||
Streamr: Nobody's using it, no migration planned
|
||||
Streamr: Just switch, nobody's using it
|
||||
|
||||
SAM UDP apps: None known
|
||||
|
||||
@ -398,20 +138,11 @@ SAM UDP apps: None known
|
||||
References
|
||||
==========
|
||||
|
||||
.. [API]
|
||||
{{ site_url('docs/api/datagrams', True) }}
|
||||
|
||||
.. [BT-SPEC]
|
||||
{{ site_url('docs/applications/bittorrent', True) }}
|
||||
|
||||
.. [Common]
|
||||
{{ spec_url('common-structures') }}
|
||||
|
||||
.. [DATAGRAMS]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
.. [I2CP]
|
||||
{{ site_url('docs/protocol/i2cp', True) }}
|
||||
{{ spec_url('i2cp') }}
|
||||
|
||||
.. [Prop123]
|
||||
{{ proposal_url('123') }}
|
||||
@ -419,15 +150,5 @@ References
|
||||
.. [Prop160]
|
||||
{{ proposal_url('160') }}
|
||||
|
||||
.. [Prop164]
|
||||
{{ proposal_url('164') }}
|
||||
|
||||
.. [Streaming]
|
||||
{{ spec_url('streaming') }}
|
||||
|
||||
.. [TRANSPORT]
|
||||
{{ site_url('docs/transport', True) }}
|
||||
|
||||
.. [TUNMSG]
|
||||
{{ spec_url('tunnel-message') }}#notes
|
||||
|
||||
.. [BT-SPEC]
|
||||
{{ site_url('docs/applications/bittorrent', True) }}
|
||||
|
@ -1,202 +0,0 @@
|
||||
===========================
|
||||
I2P proposal #165: SSU2 fix
|
||||
===========================
|
||||
.. meta::
|
||||
:author: weko, orignal, the Anonymous, zzz
|
||||
:created: 2024-01-19
|
||||
:thread: http://i2pforum.i2p/viewforum.php?f=13
|
||||
:lastupdated: 2024-11-17
|
||||
:status: Open
|
||||
:target: 0.9.62
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
|
||||
Proposal by weko, orignal, the Anonymous and zzz.
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This document suggests changes to SSU2 following an attack on I2P that exploited vulnerabilities in SSU2. The primary goal is to enhance security and prevent Distributed Denial of Service (DDoS) attacks and de-anonymization attempts.
|
||||
|
||||
Threat model
|
||||
------------
|
||||
|
||||
An attacker creates new fake RIs (router doesn’t exist): is regular RI,
|
||||
but he puts address, port, s and i keys from real Bob’s router, then he
|
||||
floods the network. When we are trying to connect to this (as we think
|
||||
real) router, we, as Alice can connect to this address, but we can’t be
|
||||
sure what done it with real Bob’s RI. This is possible and was used for
|
||||
a Distributed Denial of Service attack (make big amount of such RIs and
|
||||
flood the network), also this can make de-anon attacks easier by framing
|
||||
good routers and do not framing attacker’s routers, if we ban IP with
|
||||
many RIs (instead better distrubute tunnel building to this RIs as to
|
||||
one router).
|
||||
|
||||
|
||||
Potential fixes
|
||||
---------------
|
||||
|
||||
1. Fix with support for old (before the change) routers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. _overview-1:
|
||||
|
||||
Overview
|
||||
^^^^^^^^
|
||||
|
||||
A workaround to support SSU2 connections with old routers.
|
||||
|
||||
Behavivor
|
||||
^^^^^^^^^
|
||||
|
||||
Bob’s router profile should have ‘verified’ flag, it’s false by default
|
||||
for all new routers (with no profile yet). When ‘verified’ flag is
|
||||
false, we never do connections with SSU2 as Alice to Bob - we can’t be
|
||||
sure in RI. If Bob connected to us (Alice) with NTCP2 or SSU2 or we
|
||||
(Alice) connected to Bob with NTCP2 once (we can verify Bob’s
|
||||
RouterIdent in these cases) - flag is set to true.
|
||||
|
||||
Problems
|
||||
^^^^^^^^
|
||||
|
||||
So, there is a problem with fake SSU2-only RI flood: we can’t verify it
|
||||
by ourselves and are forced to wait when the real router will make
|
||||
connections with us.
|
||||
|
||||
2. Verify RouterIdent during connection creation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. _overview-2:
|
||||
|
||||
Overview
|
||||
^^^^^^^^
|
||||
|
||||
Add “RouterIdent” block for SessionRequest and SessionCreated.
|
||||
|
||||
Possible format of RouterIdent block
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1 byte flags, 32 bytes RouterIdent. Flag_0: 0 if receiver’s RouterIdent;
|
||||
1 if sender’s RouterIdent
|
||||
|
||||
Behavior
|
||||
^^^^^^^^
|
||||
|
||||
Alice (should(1), can(2)) send in payload RouterIdent block Flag_0 = 0
|
||||
and Bob’s RouterIdent. Bob (should(3), can(4)) check if is it his
|
||||
RouterIdent, and if not: terminate the session with “Wrong RouterIdent”
|
||||
reason, if it is his RouterIdent: send RI block with 1 in Flag_0 and
|
||||
Bob’s RouterIdent.
|
||||
|
||||
With (1) Bob does not support old routers. With (2) Bob supports old
|
||||
routers, but can be a victim of DDoS from routers that are trying to
|
||||
make connection with fake RIs. With (3) Alice does not support old
|
||||
routers. With (4) Alice supports old routers and is using a hybrid
|
||||
scheme: Fix 1 for old routers and Fix 2 for new routers. If RI says new
|
||||
version, but while in the connection we didnt’s recieve the RouterIdent
|
||||
block - terminate and remove RI.
|
||||
|
||||
.. _problems-1:
|
||||
|
||||
Problems
|
||||
^^^^^^^^
|
||||
|
||||
An attacker can mask his fake routers as old, and with (4) we are
|
||||
waiting for ‘verified’ as in fix 1 anyways.
|
||||
|
||||
Notes
|
||||
^^^^^
|
||||
|
||||
Instead of 32 byte RouterIdent, we can probably use 4 byte
|
||||
siphash-of-the-hash, some HKDF or something else, which must be
|
||||
sufficient.
|
||||
|
||||
3. Bob sets i = RouterIdent
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. _overview-3:
|
||||
|
||||
Overview
|
||||
^^^^^^^^
|
||||
|
||||
Bob uses his RouterIdent as i key.
|
||||
|
||||
.. _behavior-1:
|
||||
|
||||
Behavior
|
||||
^^^^^^^^
|
||||
|
||||
Bob (should(1), can(2)) uses his own RouterIdent as i key for SSU2.
|
||||
|
||||
Alice with (1) connects only if i = Bob’s RouterIdent. Alice with (2)
|
||||
uses the hybrid scheme (fix 3 and 1): if i = Bob’s RouterIdent, we can
|
||||
make the connection, otherwise we should verify it first (see fix 1).
|
||||
|
||||
With (1) Alice does not support old routers. With (2) Alice supports old
|
||||
routers.
|
||||
|
||||
.. _problems-2:
|
||||
|
||||
Problems
|
||||
^^^^^^^^
|
||||
|
||||
An attacker can mask his fake routers as old, and with (2) we are
|
||||
waiting for ‘verified’ as in fix 1 anyways.
|
||||
|
||||
.. _notes-1:
|
||||
|
||||
Notes
|
||||
^^^^^
|
||||
|
||||
To save on RI size, better add handling if i key isn’t specified. If it
|
||||
is, then i = RouterIdent. In that case, Bob does not support old
|
||||
routers.
|
||||
|
||||
4. Add one more MixHash to KDF of SessionRequest
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. _overview-4:
|
||||
|
||||
Overview
|
||||
^^^^^^^^
|
||||
|
||||
Add MixHash(Bob's ident hash) to NOISE state of "SessionRequest" message, e.g.
|
||||
h = SHA256 (h || Bob's ident hash).
|
||||
It must be last MixHash used as ad for ENCYPT or DECRYPT.
|
||||
Additional SSU2 header flag "Verify Bob's ident" = 0x02 must be introduced.
|
||||
|
||||
.. _behavior-4:
|
||||
|
||||
Behavior
|
||||
^^^^^^^^
|
||||
|
||||
- Alice adds MixHash with Bob's ident hash from Bob's RouterInfo and use it as ad for ENCRYPT and sets "Verify Bob's ident" flag
|
||||
- Bob checks "Verify Bob's ident" flag and adds MixHash with own ident hash and use it ad as for DECRYPT. Is AEAD/Chacha20/Poly1305 fails, Bob closes the session.
|
||||
|
||||
Compatibity with older routers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Alice must check Bob's router version and if it satisfies miminal version supporting this proposal add this MixHash and set "Verify Bob's ident" flag. If router is older, Alice doesn't add MixHash and doesn't set "Verify Bob's ident" flag.
|
||||
- Bob checks "Verify Bob's ident" flag and adds this MixHash if it's set. Older router don't set this flag and this MixHash shouldn't be added.
|
||||
|
||||
.. _problems-4:
|
||||
|
||||
Problems
|
||||
^^^^^^^^
|
||||
|
||||
- An attacker can claim fake routers with older version. At some point olders router should be used with precaution and after they got verified by other ways.
|
||||
|
||||
|
||||
Backward compability
|
||||
--------------------
|
||||
|
||||
Described in fixes.
|
||||
|
||||
|
||||
Current status
|
||||
--------------
|
||||
|
||||
i2pd: Fix 1.
|
@ -1,285 +0,0 @@
|
||||
===================================================
|
||||
I2P proposal #166: Identity/Host Aware Tunnel Types
|
||||
===================================================
|
||||
.. meta::
|
||||
:author: eyedeekay
|
||||
:created: 2024-05-27
|
||||
:thread: http://i2pforum.i2p/viewforum.php?f=13
|
||||
:lastupdated: 2024-08-27
|
||||
:status: Open
|
||||
:target: 0.9.65
|
||||
|
||||
.. contents::
|
||||
|
||||
Proposal for a Host-Aware HTTP Proxy Tunnel Type
|
||||
------------------------------------------------
|
||||
|
||||
This is a proposal to resolve the “Shared Identity Problem” in
|
||||
conventional HTTP-over-I2P usage by introducing a new HTTP proxy tunnel
|
||||
type. This tunnel type has supplemental behavior which is intended to
|
||||
prevent or limit the utility of tracking conducted by potential hostile
|
||||
hidden service operators, against targeted user-agents(browsers) and the
|
||||
I2P Client Application itself.
|
||||
|
||||
What is the “Shared Identity” problem?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The “Shared Identity” problem occurs when a user-agent on a
|
||||
cryptographically addressed overlay network shares a cryptographic
|
||||
identity with another user-agent. This occurs, for instance, when a
|
||||
Firefox and GNU Wget are both configured to use the same HTTP Proxy.
|
||||
|
||||
In this scenario, it is possible for the server to collect and store the
|
||||
cryptographic address(Destination) used to reply to the activity. It can
|
||||
treat this as a “Fingerprint” which is always 100% unique, because it is
|
||||
cryptographic in origin. This means that the linkability observed by the
|
||||
Shared Identity problem is perfect.
|
||||
|
||||
But is it a problem?
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The shared identity problem is a problem when user-agents that speak the
|
||||
same protocol desire unlinkability. `It was first mentioned in the
|
||||
context of HTTP in this Reddit
|
||||
Thread <https://old.reddit.com/r/i2p/comments/579idi/warning_i2p_is_linkablefingerprintable/>`__,
|
||||
with the deleted comments accessible courtesy of
|
||||
`pullpush.io <https://api.pullpush.io/reddit/search/comment/?link_id=579idi>`__.
|
||||
*At the time* I was one of the most active respondents, and *at the
|
||||
time* I believed the issue was small. In the past 8 years, the situation
|
||||
and my opinion of it have changed, I now believe the threat posed by
|
||||
malicious destination correlation grows considerably as more sites are
|
||||
in a position to “profile” specific users.
|
||||
|
||||
This attack has a very low barrier to entry. It only requires that a
|
||||
hidden service operator operate multiple services. For attacks on
|
||||
contemporary visits(visiting multiple sites at the same time), this is
|
||||
the only requirement. For non-contemporary linking, one of those
|
||||
services must be a service which hosts “accounts” which belong to a
|
||||
single user who is targeted for tracking.
|
||||
|
||||
Currently, any service operator who hosts user accounts will be able to
|
||||
correlate them with activity across any sites they control by exploiting
|
||||
the Shared Identity problem. Mastodon, Gitlab, or even simple forums
|
||||
could be attackers in disguise as long as they operate more than one
|
||||
service and have an interest in creating a profile for a user. This
|
||||
surveillance could be conducted for stalking, financial gain, or
|
||||
intelligence-related reasons. Right now there are dozens of major
|
||||
operators, who could carry out this attack and gain meaningful data from
|
||||
it. We mostly trust them not to for now, but players who don’t care
|
||||
about our opinions could easily emerge.
|
||||
|
||||
This is directly related to a fairly basic form of profile-building on
|
||||
the clear web where organizations can correlate interactions on their
|
||||
site with interations on networks they control. On I2P, because the
|
||||
cryptographic destination is unique, this technique can sometimes be
|
||||
even more reliable, albeit without the additional power of geolocation.
|
||||
|
||||
The Shared Identity is not useful against a user who is using I2P solely
|
||||
to obfuscate geolocation. It also cannot be used to break I2P’s routing.
|
||||
It is only a problem of contextual identity management.
|
||||
|
||||
- It is impossible to use the Shared Identity problem to geolocate an
|
||||
I2P user.
|
||||
- It is impossible to use the Shared Identity problem to link I2P
|
||||
sessions if they are not contemporary.
|
||||
|
||||
However, it is possible to use it to degrade the anonymity of an I2P
|
||||
user in circumstances which are probably very common. One reason they
|
||||
are common is becase we encourage the use of Firefox, a web browser
|
||||
which supports “Tabbed” operation.
|
||||
|
||||
- It is *always* possible to produce a fingerprint from the Shared
|
||||
Identity problem in *any* web browser which supports requesting
|
||||
third-party resources.
|
||||
- Disabling Javascript accomplishes **nothing** against the Shared
|
||||
Identity problem.
|
||||
- If a link can be established between non-contemporary sessions such
|
||||
as by “traditional” browser fingerprinting, then the Shared Identity
|
||||
can be applied transitively, potentially enabling a non-contemporary
|
||||
linking strategy.
|
||||
- If a link can be established between a clearnet activity and an I2P
|
||||
identity, for instance, if the target is logged into a site with both
|
||||
an I2P and a clearnet presence on both sides, the Shared Identity can
|
||||
be applied transitively, potentially enabling complete
|
||||
de-anonymization.
|
||||
|
||||
How you view the severity of the Shared Identity problem as it applies
|
||||
to the I2P HTTP proxy depends on where you(or more to the point, a
|
||||
“user” with potentially uninformed expectationss) think the “contextual
|
||||
identity” for the application lies. There are several possibilities:
|
||||
|
||||
1. HTTP is both the Application and the Contextual Identity - This is
|
||||
how it works now. All HTTP Applications share an identity.
|
||||
2. The Process is the Application and the Contextual Identity - This is
|
||||
how it works when an application uses an API like SAMv3 or I2CP,
|
||||
where an application creates it’s identity and controls it’s
|
||||
lifetime.
|
||||
3. HTTP is the Application, but the Host is the Contextual Identity
|
||||
-This is the object of this proposal, which treats each Host as a
|
||||
potential “Web Application” and treats the threat surface as such.
|
||||
|
||||
Is it Solvable?
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
It is probably not possible to make a proxy which intelligently responds
|
||||
to every possible case in which it’s operation could weaken the
|
||||
anonymity of an application. However, it is possible to build a proxy
|
||||
which intelligently responds to a specific application which behaves in
|
||||
a predictable way. For instance, in modern Web Browsers, it is expected
|
||||
that users will have multiple tabs open, where they will be interacting
|
||||
with multiple web sites, which will be distinguished by hostname.
|
||||
|
||||
This allows us to improve upon the behavior of the HTTP Proxy for this
|
||||
type of HTTP user-agent by making the behavior of the proxy match the
|
||||
behavior of the user-agent by giving each host it’s own Destination when
|
||||
used with the HTTP Proxy. This change makes it impossible to use the
|
||||
Shared Identity problem to derive a fingerprint which can be used to
|
||||
correlate client activity with 2 hosts, because the 2 hosts will simply
|
||||
no longer share a return identity.
|
||||
|
||||
Description:
|
||||
^^^^^^^^^^^^
|
||||
|
||||
A new HTTP Proxy will be created and added to Hidden Services
|
||||
Manager(I2PTunnel). The new HTTP Proxy will operate as a “multiplexer”
|
||||
of I2PSocketManagers. The multiplexer itself has no destination. Each
|
||||
individual I2PSocketManager which becomes part of the multiplex has it’s own
|
||||
local destination, and it’s own tunnel pool. I2PSocketManagerss are created
|
||||
on-demand by the multiplexer, where the “demand” is the first visit to the
|
||||
new host. It is possible to optimize the creation of the I2PSocketManagers
|
||||
before inserting them into the multiplexer by creating one or more in advance
|
||||
and storing them outside the multiplexer. This may improve performance.
|
||||
|
||||
An additional I2PSocketManager, with it’s own destination, is set up as the
|
||||
carrier of an “Outproxy” for any site which does *not* have an I2P
|
||||
Destination, for example any Clearnet site. This effectively makes all
|
||||
Outproxy usage a single Contextual Identity, with the caveat that
|
||||
configuring multiple Outproxies for the tunnel will cause the normal
|
||||
“Sticky” outproxy rotation, where each outproxy only gets requests for a
|
||||
single site. This is *almost* the equivalent behavior as isolating
|
||||
HTTP-over-I2P proxies by destination, on the clear internet.
|
||||
|
||||
Resource Considerations:
|
||||
''''''''''''''''''''''''
|
||||
|
||||
The new HTTP proxy requires additional resources compared to the
|
||||
existing HTTP proxy. It will:
|
||||
|
||||
- Potentially build more tunnels and I2PSocketManagers
|
||||
- Build tunnels more often
|
||||
|
||||
Each of these requires:
|
||||
|
||||
- Local computing resources
|
||||
- Network resources from peers
|
||||
|
||||
Settings:
|
||||
'''''''''
|
||||
|
||||
In order to minimize the impact of the increased resource usage, the
|
||||
proxy should be configured to use as little as possible. Proxies which
|
||||
are part of the multiplexer(not the parent proxy) should be configured
|
||||
to:
|
||||
|
||||
- Multiplexed I2PSocketManagers build 1 tunnel in, 1 tunnel out in their
|
||||
tunnel pools
|
||||
- Multiplexed I2PSocketManagers take 3 hops by default.
|
||||
- Close sockets after 10 minutes of inactivity
|
||||
- I2PSocketManagers started by the Multiplexer share the lifespan of the
|
||||
Multiplexer. Multiplexed tunnels are not “Destructed” until the
|
||||
parent Multiplexer is.
|
||||
|
||||
Diagrams:
|
||||
^^^^^^^^^
|
||||
|
||||
The diagram below represents the current operation of the HTTP proxy,
|
||||
which corresponds to “Possibility 1.” under the “Is it a problem”
|
||||
section. As you can see, the HTTP proxy interacts with I2P sites
|
||||
directly using only one destination. In this scenario, HTTP is both the
|
||||
application and the contextual identity.
|
||||
|
||||
.. code:: md
|
||||
|
||||
**Current Situation: HTTP is the Application, HTTP is the Contextual Identity**
|
||||
__-> Outproxy <-> i2pgit.org
|
||||
/
|
||||
Browser <-> HTTP Proxy(one Destination)<->I2PSocketManager <---> idk.i2p
|
||||
\__-> translate.idk.i2p
|
||||
\__-> git.idk.i2p
|
||||
|
||||
The diagram below represents the operation of a host-aware HTTP proxy,
|
||||
which corresponds to “Possibility 3.” under the “Is it a problem”
|
||||
section. In this secenario, HTTP is the application, but the Host
|
||||
defines the contextual identity, wherein each I2P site interacts with a
|
||||
different HTTP proxy with a unique destination per-host. This prevents
|
||||
operators of multiple sites from being able to distinguish when the same
|
||||
person is visiting multiple sites which they operate.
|
||||
|
||||
.. code:: md
|
||||
|
||||
**After the Change: HTTP is the Application, Host is the Contextual Identity**
|
||||
__-> I2PSocketManager(Destination A - Outproxies Only) <--> i2pgit.org
|
||||
/
|
||||
Browser <-> HTTP Proxy Multiplexer(No Destination) <---> I2PSocketManager(Destination B) <--> idk.i2p
|
||||
\__-> I2PSocketManager(Destination C) <--> translate.idk.i2p
|
||||
\__-> I2PSocketManager(Destination C) <--> git.idk.i2p
|
||||
|
||||
Status:
|
||||
^^^^^^^
|
||||
|
||||
A working Java implementation of the host-aware proxy which conforms to
|
||||
an older version of this proposal is available at idk's fork under the
|
||||
branch: i2p.i2p.2.6.0-browser-proxy-post-keepalive Link in citations. It
|
||||
is under heavy revision, in order to break down the changes into smaller
|
||||
sections.
|
||||
|
||||
Implementations with varying capabilities have been written in Go using
|
||||
the SAMv3 library, they may be useful for embedding in other Go
|
||||
applications or for go-i2p but are unsuitable for Java I2P.
|
||||
Additionally, they lack good support for working interactively with
|
||||
encrypted leaseSets.
|
||||
|
||||
Addendum: ``i2psocks``
|
||||
|
||||
|
||||
A simple application-oriented approach to isolating other types of
|
||||
clients is possible without implementing a new tunnel type or changing
|
||||
the existing I2P code by combining I2PTunnel existing tools which are
|
||||
already widely available and tested in the privacy community. However,
|
||||
this approach makes a difficult assumption which is not true for HTTP
|
||||
and also not true for many other kinds of potentsial I2P clients.
|
||||
|
||||
Roughly, the following script will produce an application-aware SOCKS5
|
||||
proxy and socksify the underlying command:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
#! /bin/sh
|
||||
command_to_proxy="$@"
|
||||
java -jar ~/i2p/lib/i2ptunnel.jar -wait -e 'sockstunnel 7695'
|
||||
torsocks --port 7695 $command_to_proxy
|
||||
|
||||
Addendum: ``example implementation of the attack``
|
||||
|
||||
|
||||
`An example implementation of the Shared Identity attack on HTTP
|
||||
User-Agents <https://github.com/eyedeekay/colluding_sites_attack/>`__
|
||||
has existed for several years. An additional example is available in the
|
||||
``simple-colluder`` subdirectory of `idk’s prop166
|
||||
repository <https://git.idk.i2p/idk/i2p.host-aware-proxy>`__ These
|
||||
examples are deliberately designed to demonstrate that the attack works
|
||||
and would require modification(albeit minor) to be turned into a real
|
||||
attack.
|
||||
|
||||
Citations:
|
||||
''''''''''
|
||||
|
||||
https://old.reddit.com/r/i2p/comments/579idi/warning_i2p_is_linkablefingerprintable/
|
||||
https://api.pullpush.io/reddit/search/comment/?link_id=579idi
|
||||
https://github.com/eyedeekay/colluding_sites_attack/
|
||||
https://en.wikipedia.org/wiki/Shadow_profile
|
||||
https://github.com/eyedeekay/si-i2p-plugin/
|
||||
https://github.com/eyedeekay/eeproxy/
|
||||
https://geti2p.net/en/docs/api/socks
|
||||
https://i2pgit.org/idk/i2p.www/-/compare/master...166-identity-aware-proxies?from_project_id=17
|
||||
https://i2pgit.org/idk/i2p.i2p/-/tree/i2p.i2p.2.6.0-browser-proxy-post-keepalive?ref_type=heads
|
@ -1,448 +0,0 @@
|
||||
===================================
|
||||
Service Records in LS2
|
||||
===================================
|
||||
.. meta::
|
||||
:author: zzz, orignal, eyedeekay
|
||||
:created: 2024-06-22
|
||||
:thread: http://zzz.i2p/topics/3641
|
||||
:lastupdated: 2025-04-03
|
||||
:status: Closed
|
||||
:target: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Status
|
||||
======
|
||||
Approved on 2nd review 2025-04-01; specs are updated; not yet implemented.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
I2P lacks a centralized DNS system.
|
||||
However, the address book, together with the b32 hostname system, allows
|
||||
the router to look up full destinations and fetch lease sets, which contain
|
||||
a list of gateways and keys so that clients may connect to that destination.
|
||||
|
||||
So, leasesets are somewhat like a DNS record. But there is currently no facility to
|
||||
find out if that host supports any services, either on that destination or a different one,
|
||||
in a manner similar to DNS SRV records [SRV]_ [RFC2782]_.
|
||||
|
||||
The first application for this may be peer-to-peer email.
|
||||
Other possible applications: DNS, GNS, key servers, certificate authorities, time servers,
|
||||
bittorrent, cryptocurrencies, other peer-to-peer applications.
|
||||
|
||||
|
||||
Related Proposals and Alternatives
|
||||
==================================
|
||||
|
||||
Service Lists
|
||||
--------------
|
||||
|
||||
The LS2 proposal 123 [Prop123]_ defined 'service records' that indicated a destination
|
||||
was participating in a global service. The floodfills would aggregate these records
|
||||
into global 'service lists'.
|
||||
This was never implemented due to complexity, lack of authentication,
|
||||
security, and spamming concerns.
|
||||
|
||||
This proposal is different in that it provides lookup for a service for a specific destination,
|
||||
not a global pool of destinations for some global service.
|
||||
|
||||
GNS
|
||||
-----
|
||||
|
||||
GNS [GNS]_ proposes that everybody runs their own DNS server.
|
||||
This proposal is complementary, in that we could use service records to specify
|
||||
that GNS (or DNS) is supported, with a standard service name of "domain" on port 53.
|
||||
|
||||
Dot well-known
|
||||
---------------
|
||||
|
||||
In [DOTWELLKNOWN]_ it is proposed that services be looked up via an HTTP request to
|
||||
/.well-known/i2pmail.key. This requires that every service must have a related
|
||||
website to host the key. Most users do not run websites.
|
||||
|
||||
One workaround is that we could presume that a service for a b32 address is actually
|
||||
running on that b32 address. So that looking for the service for example.i2p requires
|
||||
the HTTP fetch from http://example.i2p/.well-known/i2pmail.key, but
|
||||
a service for aaa...aaa.b32.i2p does not require that lookup, it can just connect directly.
|
||||
|
||||
But there's an ambiguity there, because example.i2p can also be addressed by its b32.
|
||||
|
||||
MX Records
|
||||
----------
|
||||
|
||||
SRV records are simply a generic version of MX records for any service.
|
||||
"_smtp._tcp" is the "MX" record.
|
||||
There is no need for MX records if we have SRV records, and MX records
|
||||
alone do not provide a generic record for any service.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
Service records are placed in the options section in LS2 [LS2]_.
|
||||
The LS2 options section is currently unused.
|
||||
Not supported for LS1.
|
||||
This is similar to the tunnel bandwidth proposal [Prop168]_,
|
||||
which defines options for tunnel build records.
|
||||
|
||||
To lookup a service address for a specific hostname or b32, the router fetches the
|
||||
leaseset and looks up the service record in the properties.
|
||||
|
||||
The service may be hosted on the same destination as the LS itself, or may reference
|
||||
a different hostname/b32.
|
||||
|
||||
If the target destination for the service is different, the target LS must also
|
||||
include a service record, pointing to itself, indicating that it supports the service.
|
||||
|
||||
The design does not require special support or caching or any changes in the floodfills.
|
||||
Only the leaseset publisher, and the client looking up a service record,
|
||||
must support these changes.
|
||||
|
||||
Minor I2CP and SAM extensions are proposed to facilitate retrieval of
|
||||
service records by clients.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
LS2 Option Specification
|
||||
---------------------------
|
||||
|
||||
LS2 options MUST be sorted by key, so the signature is invariant.
|
||||
|
||||
Defined as follows:
|
||||
|
||||
- serviceoption := optionkey optionvalue
|
||||
- optionkey := _service._proto
|
||||
- service := The symbolic name of the desired service. Must be lower case. Example: "smtp".
|
||||
Allowed chars are [a-z0-9-] and must not start or end with a '-'.
|
||||
Standard identifiers from [REGISTRY]_ or Linux /etc/services must be used if defined there.
|
||||
- proto := The transport protocol of the desired service. Must be lower case, either "tcp" or "udp".
|
||||
"tcp" means streaming and "udp" means repliable datagrams.
|
||||
Protocol indicators for raw datagrams and datagram2 may be defined later.
|
||||
Allowed chars are [a-z0-9-] and must not start or end with a '-'.
|
||||
- optionvalue := self | srvrecord[,srvrecord]*
|
||||
- self := "0" ttl port [appoptions]
|
||||
- srvrecord := "1" ttl priority weight port target [appoptions]
|
||||
- ttl := time to live, integer seconds. Positive integer. Example: "86400".
|
||||
A minimum of 86400 (one day) is recommended, see Recommendations section below for details.
|
||||
- priority := The priority of the target host, lower value means more preferred. Non-negative integer. Example: "0"
|
||||
Only useful if more than one record, but required even if just one record.
|
||||
- weight := A relative weight for records with the same priority. Higher value means more chance of getting picked. Non-negative integer. Example: "0"
|
||||
Only useful if more than one record, but required even if just one record.
|
||||
- port := The I2CP port on which the service is to be found. Non-negative integer. Example: "25"
|
||||
Port 0 is supported but not recommended.
|
||||
- target := The hostname or b32 of the destination providing the service. A valid hostname as in [NAMING]_. Must be lower case.
|
||||
Example: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p" or "example.i2p".
|
||||
b32 is recommended unless the hostname is "well known", i.e. in official or default address books.
|
||||
- appoptions := arbitrary text specific to the application, must not contain " " or ",". Encoding is UTF-8.
|
||||
|
||||
Examples
|
||||
``````````
|
||||
|
||||
In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to one SMTP server:
|
||||
|
||||
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
|
||||
|
||||
In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to two SMTP servers:
|
||||
|
||||
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p,86400 1 0 25 cccccccccccccccccccccccccccccccccccccccccccc.b32.i2p"
|
||||
|
||||
In LS2 for bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p, pointing to itself as a SMTP server:
|
||||
|
||||
"_smtp._tcp" "0 999999 25"
|
||||
|
||||
Possible format for redirecting email (see below):
|
||||
|
||||
"_smtp._tcp" "1 86400 0 0 25 smtp.postman.i2p example@mail.i2p"
|
||||
|
||||
|
||||
Limits
|
||||
```````
|
||||
|
||||
The Mapping data structure format used for LS2 options limits keys and values to 255 bytes (not chars) max.
|
||||
With a b32 target, the optionvalue is about 67 bytes, so only 3 records would fit.
|
||||
Maybe only one or two with a long appoptions field, or up to four or five with a short hostname.
|
||||
This should be sufficient; multiple records should be rare.
|
||||
|
||||
|
||||
Differences from [RFC2782]_
|
||||
````````````````````````````
|
||||
|
||||
- No trailing dots
|
||||
- No name after the proto
|
||||
- Lower case required
|
||||
- In text format with comma-separated records, not binary DNS format
|
||||
- Different record type indicators
|
||||
- Additional appoptions field
|
||||
|
||||
|
||||
Notes
|
||||
`````
|
||||
|
||||
No wildcarding such as (asterisk), (asterisk)._tcp, or _tcp is allowed.
|
||||
Each supported service must have its own record.
|
||||
|
||||
|
||||
|
||||
Service Name Registry
|
||||
----------------------
|
||||
|
||||
Non-standard identifiers that are not listed in [REGISTRY]_ or Linux /etc/services
|
||||
may be requested and added to the common structures specification [LS2]_.
|
||||
|
||||
Service-specific appoptions formats may also be added there.
|
||||
|
||||
|
||||
I2CP Specification
|
||||
------------------
|
||||
|
||||
The [I2CP]_ protocol must be extended to support service lookups.
|
||||
Additional MessageStatusMessage and/or HostReplyMessage error codes related to service lookup
|
||||
are required.
|
||||
To make the lookup facility general, not just service record-specific,
|
||||
the design is to support retrieval of all LS2 options.
|
||||
|
||||
Implementation: Extend HostLookupMessage to add request for
|
||||
LS2 options for hash, hostname, and destination (request types 2-4).
|
||||
Extend HostReplyMessage to add the options mapping if requested.
|
||||
Extend HostReplyMessage with additional error codes.
|
||||
|
||||
Options mappings may be cached or negative cached for a short time on either the client or router side,
|
||||
implementation-dependent. Recommended maximum time is one hour, unless the service record TTL is shorter.
|
||||
Service records may be cached up to the TTL specified by the application, client, or router.
|
||||
|
||||
Extend the specification as follows:
|
||||
|
||||
Configuration options
|
||||
`````````````````````
|
||||
Add the following to [I2CP-OPTIONS]
|
||||
|
||||
i2cp.leaseSetOption.nnn
|
||||
|
||||
Options to be put in the leaseset. Only available for LS2.
|
||||
nnn starts with 0. Option value contains "key=value".
|
||||
(do not include quotes)
|
||||
|
||||
Example:
|
||||
i2cp.leaseSetOption.0=_smtp._tcp=1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p
|
||||
|
||||
|
||||
HostLookup Message
|
||||
``````````````````
|
||||
|
||||
- Lookup type 2: Hash lookup, request options mapping
|
||||
- Lookup type 3: Hostname lookup, request options mapping
|
||||
- Lookup type 4: Destination lookup, request options mapping
|
||||
|
||||
For lookup type 4, item 5 is a Destination.
|
||||
|
||||
|
||||
|
||||
HostReply Message
|
||||
``````````````````
|
||||
|
||||
For lookup types 2-4, the router must fetch the leaseset,
|
||||
even if the lookup key is in the address book.
|
||||
|
||||
If successful, the HostReply will contain the options Mapping
|
||||
from the leaseset, and includes it as item 5 after the destination.
|
||||
If there are no options in the Mapping, or the leaseset was version 1,
|
||||
it will still be included as an empty Mapping (two bytes: 0 0).
|
||||
All options from the leaseset will be included, not just service record options.
|
||||
For example, options for parameters defined in the future may be present.
|
||||
|
||||
On leaseset lookup failure, the reply will contain a new error code 6 (Leaseset lookup failure)
|
||||
and will not include a mapping.
|
||||
When error code 6 is returned, the Destination field may or may not be present.
|
||||
It will be present if a hostname lookup in the address book was successful,
|
||||
or if a previous lookup was successful and the result was cached,
|
||||
or if the Destination was present in the lookup message (lookup type 4).
|
||||
|
||||
If a lookup type is not supported,
|
||||
the reply will contain a new error code 7 (lookup type unsupported).
|
||||
|
||||
|
||||
|
||||
SAM Specification
|
||||
------------------
|
||||
|
||||
The [SAMv3]_ protocol must be extended to support service lookups.
|
||||
|
||||
Extend NAMING LOOKUP as follows:
|
||||
|
||||
NAMING LOOKUP NAME=example.i2p OPTIONS=true requests the options mapping in the reply.
|
||||
|
||||
NAME may be a full base64 destination when OPTIONS=true.
|
||||
|
||||
If the destination lookup was successful and options were present in the leaseset,
|
||||
then in the reply, following the destination,
|
||||
will be one or more options in the form of OPTION:key=value.
|
||||
Each option will have a separate OPTION: prefix.
|
||||
All options from the leaseset will be included, not just service record options.
|
||||
For example, options for parameters defined in the future may be present.
|
||||
Example:
|
||||
|
||||
NAMING REPLY RESULT=OK NAME=example.i2p VALUE=base64dest OPTION:_smtp._tcp="1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
|
||||
|
||||
Keys containing '=', and keys or values containing a newline,
|
||||
are considered invalid and the key/value pair will be removed from the reply.
|
||||
|
||||
If there are no options found in the leaseset, or if the leaseset was version 1,
|
||||
then the response will not include any options.
|
||||
|
||||
If OPTIONS=true was in the lookup, and the leaseset is not found, a new result value LEASESET_NOT_FOUND will be returned.
|
||||
|
||||
|
||||
Naming Lookup Alternative
|
||||
==========================
|
||||
|
||||
An alternative design was considered, to support lookups of services
|
||||
as a full hostname, for example _smtp._tcp.example.i2p,
|
||||
by updating [NAMING]_ to specify handling of hostnames starting with '_'.
|
||||
This was rejected for two reasons:
|
||||
|
||||
- I2CP and SAM changes would still be necessary to pass through the TTL and port information to the client.
|
||||
- It would not be a general facility that could be used to retrieve other LS2
|
||||
options that could be defined in the future.
|
||||
|
||||
|
||||
Recommendations
|
||||
================
|
||||
|
||||
Servers should specify a TTL of at least 86400, and the standard port for the application.
|
||||
|
||||
|
||||
|
||||
Advanced Features
|
||||
==================
|
||||
|
||||
Recursive Lookups
|
||||
----------------------
|
||||
|
||||
It may be desirable to support recursive lookups, where each successive leaseset
|
||||
is checked for a service record pointing to another leaseset, DNS-style.
|
||||
This is probably not necessary, at least in an initial implementation.
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
|
||||
Application-specific fields
|
||||
-----------------------------
|
||||
|
||||
It may be desirable to have application-specific data in the service record.
|
||||
For example, the operator of example.i2p may wish to indicate that email should
|
||||
be forwarded to example@mail.i2p. The "example@" part would need to be in a separate field
|
||||
of the service record, or stripped from the target.
|
||||
|
||||
Even if the operator runs his own email service, he may wish to indicate that
|
||||
email should be sent to example@example.i2p. Most I2P services are run by a single person.
|
||||
So a separate field may be helpful here as well.
|
||||
|
||||
TODO how to do this in a generic way
|
||||
|
||||
|
||||
Changes required for Email
|
||||
------------------------------
|
||||
|
||||
Out of the scope of this proposal. See [DOTWELLKNOWN]_ for a discussion.
|
||||
|
||||
|
||||
Implementation Notes
|
||||
=====================
|
||||
|
||||
Caching of service records up to the TTL may be done by the router or the application,
|
||||
implementation-dependent. Whether to cache persistently is also implementation-dependent.
|
||||
|
||||
Lookups must also lookup the target leaseset and verify it contains a "self" record
|
||||
before returning the target destination to the client.
|
||||
|
||||
|
||||
Security Analysis
|
||||
=================
|
||||
|
||||
As the leaseset is signed, any service records within it are authenticated by the signing key of the destination.
|
||||
|
||||
The service records are public and visible to floodfills, unless the leaseset is encrypted.
|
||||
Any router requesting the leaseset will be able to see the service records.
|
||||
|
||||
A SRV record other than "self" (i.e., one that points to a different hostname/b32 target)
|
||||
does not require the consent of the targeted hostname/b32.
|
||||
It's not clear if a redirection of a service to an arbitrary destination could facilitate some
|
||||
sort of attack, or what the purpose of such an attack would be.
|
||||
However, this proposal mitigates such an attack by requiring that the target
|
||||
also publish a "self" SRV record. Implementers must check for a "self" record
|
||||
in the leaseset of the target.
|
||||
|
||||
|
||||
Compatibility
|
||||
===============
|
||||
|
||||
LS2: No issues. All known implementations currently ignore the options field in LS2,
|
||||
and correctly skip over a non-empty options field.
|
||||
This was verified in testing by both Java I2P and i2pd during the development of LS2.
|
||||
LS2 was implemented in 0.9.38 in 2016 and is well-supported by all router implementations.
|
||||
The design does not require special support or caching or any changes in the floodfills.
|
||||
|
||||
Naming: '_' is not a valid character in i2p hostnames.
|
||||
|
||||
I2CP: Lookup types 2-4 should not be sent to routers below the minimum API version
|
||||
at which it is supported (TBD).
|
||||
|
||||
SAM: Java SAM server ignores additional keys/values such as OPTIONS=true.
|
||||
i2pd should as well, to be verified.
|
||||
SAM clients will not get the additional values in the reply unless requested with OPTIONS=true.
|
||||
No version bump should be necessary.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Implementations may add support at any time, no coordination is needed,
|
||||
except for an agreement on the effective API version for the I2CP changes.
|
||||
SAM compatibility versions for each implementation will be documented in the SAM spec.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [DOTWELLKNOWN]
|
||||
http://i2pforum.i2p/viewtopic.php?p=3102
|
||||
|
||||
.. [I2CP]
|
||||
{{ spec_url('i2cp') }}
|
||||
|
||||
.. [I2CP-OPTIONS]
|
||||
{{ site_url('docs/protocol/i2cp', True) }}
|
||||
|
||||
.. [LS2]
|
||||
{{ spec_url('common-structures') }}
|
||||
|
||||
.. [GNS]
|
||||
http://zzz.i2p/topcs/1545
|
||||
|
||||
.. [NAMING]
|
||||
{{ site_url('docs/naming', True) }}
|
||||
|
||||
.. [Prop123]
|
||||
{{ proposal_url('123') }}
|
||||
|
||||
.. [Prop168]
|
||||
{{ proposal_url('168') }}
|
||||
|
||||
.. [REGISTRY]
|
||||
http://www.dns-sd.org/ServiceTypes.html
|
||||
|
||||
.. [RFC2782]
|
||||
https://datatracker.ietf.org/doc/html/rfc2782
|
||||
|
||||
.. [SAMv3]
|
||||
{{ site_url('docs/api/samv3') }}
|
||||
|
||||
.. [SRV]
|
||||
https://en.wikipedia.org/wiki/SRV_record
|
@ -1,200 +0,0 @@
|
||||
===================================
|
||||
Tunnel Bandwidth Parameters
|
||||
===================================
|
||||
.. meta::
|
||||
:author: zzz
|
||||
:created: 2024-07-31
|
||||
:thread: http://zzz.i2p/topics/3652
|
||||
:lastupdated: 2024-12-10
|
||||
:status: Closed
|
||||
:target: 0.9.65
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
|
||||
NOTE
|
||||
====
|
||||
|
||||
This proposal was approved and is now in the
|
||||
[Tunnel-Creation-ECIES]_ specification as of API 0.9.65.
|
||||
There are no known implementations yet; implementation dates / API versions are TBD.
|
||||
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
As we have increased the performance of the network over the last several years
|
||||
with new protocols, encryption types, and congestion control improvements,
|
||||
faster applications such as video streaming are becoming possible.
|
||||
These applications require high bandwidth at each hop in their client tunnels.
|
||||
|
||||
Participating routers, however, do not have any information about how much
|
||||
bandwidth a tunnel will use when they get a tunnel build message.
|
||||
They can only accept or reject a tunnel based on the current total bandwidth
|
||||
used by all participating tunnels and the total bandwidth limit for participating tunnels.
|
||||
|
||||
Requesting routers also do not have any information on how much bandwidth
|
||||
is available at each hop.
|
||||
|
||||
Also, routers currently have no way to limit inbound traffic on a tunnel.
|
||||
This would be quite useful during times of overload or DDoS of a service.
|
||||
|
||||
This proposal addresses these issues by adding bandwidth parameters to
|
||||
the tunnel build request and reply messages.
|
||||
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
Add bandwidth parameters to the records in ECIES tunnel build messages [Tunnel-Creation-ECIES]_
|
||||
in the tunnel build options mapping field. Use short parameter names since the space available
|
||||
for the options field is limited.
|
||||
Tunnel build messages are fixed-size so this does not increase the
|
||||
size of the messages.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Update the ECIES tunnel build message specification [Tunnel-Creation-ECIES]_
|
||||
as follows:
|
||||
|
||||
For both long and short ECIES build records:
|
||||
|
||||
Build Request Options
|
||||
---------------------------
|
||||
|
||||
The following three options may be set in the tunnel build options mapping field of the record:
|
||||
A requesting router may include any, all, or none.
|
||||
|
||||
- m := minimum bandwidth required for this tunnel (KBps positive integer as a string)
|
||||
- r := requested bandwidth for this tunnel (KBps positive integer as a string)
|
||||
- l := limit bandwidth for this tunnel; only sent to IBGW (KBps positive integer as a string)
|
||||
|
||||
Constraint: m <= r <= l
|
||||
|
||||
The participating router should reject the tunnel if "m" is specified and it cannot
|
||||
provide at least that much bandwidth.
|
||||
|
||||
Request options are sent to each participant in the corresponding encrypted build request record,
|
||||
and are not visible to other participants.
|
||||
|
||||
|
||||
Build Reply Option
|
||||
---------------------------
|
||||
|
||||
The following option may be set in the tunnel build reply options mapping field of the record,
|
||||
when the response is ACCEPTED:
|
||||
|
||||
- b := bandwidth available for this tunnel (KBps positive integer as a string)
|
||||
|
||||
The participating router should include this if either "m" or "r" was specified
|
||||
in the build request. The value should be at least that of the "m" value if specified,
|
||||
but may be less or more than the "r" value if specified.
|
||||
|
||||
The participating router should attempt to reserve and provide at least this
|
||||
much bandwidth for the tunnel, however this is not guaranteed.
|
||||
Routers cannot predict conditions 10 minutes into the future, and
|
||||
participating traffic is lower-priority than a router's own traffic and tunnels.
|
||||
|
||||
Routers may also over-allocate available bandwidth if necessary, and this is
|
||||
probably desirable, as other hops in the tunnel could reject it.
|
||||
|
||||
For these reasons, the participating router's reply should be treated
|
||||
as a best-effort commitment, but not a guarantee.
|
||||
|
||||
Reply options are sent to the requesting router in the corresponding encrypted build reply record,
|
||||
and are not visible to other participants.
|
||||
|
||||
|
||||
Implementation Notes
|
||||
=====================
|
||||
|
||||
Bandwidth parameters are as seen at the participating routers at the tunnel layer,
|
||||
i.e. the number of fixed-size 1 KB tunnel messages per second.
|
||||
Transport (NTCP2 or SSU2) overhead is not included.
|
||||
|
||||
This bandwidth may be much more or less than the bandwidth seen at the client.
|
||||
Tunnel messages contain substantial overhead, including overhead from higher layers
|
||||
including ratchet and streaming. Intermittent small messages such as streaming acks
|
||||
will be expanded to 1 KB each.
|
||||
However, gzip compression at the I2CP layer may substantially reduce bandwidth.
|
||||
|
||||
The simplest implementation at the requesting router is to use
|
||||
the average, minimum, and/or maximum bandwidths of current tunnels in the pool
|
||||
to calculate the values to put in the request.
|
||||
More complex algorithms are possible and are up to the implementer.
|
||||
|
||||
There are no current I2CP or SAM options defined for the client to tell the
|
||||
router what bandwidth is required, and no new options are proposed here.
|
||||
Options may be defined at a later date if necessary.
|
||||
|
||||
Implementations may use available bandwidth or any other data, algorithm, local policy,
|
||||
or local configuration to calculate the bandwidth value returned in the
|
||||
build response. Not specified by this proposal.
|
||||
|
||||
This proposal requires inbound gateways to implement per-tunnel
|
||||
throttling if requested by the "l" option.
|
||||
It does not require other participating hops to implement per-tunnel or global
|
||||
throttling of any type, or specify a particular algorithm or implementation, if any.
|
||||
|
||||
This proposal also does not require client routers to throttle traffic
|
||||
to the "b" value returned by the participating hop, and depending on application,
|
||||
that may not be possible, particularly for inbound tunnels.
|
||||
|
||||
This proposal only affects tunnels created by the originator. There is no
|
||||
method defined to request or allocate bandwidth for "far-end" tunnels created
|
||||
by the the owner of the other end of an end-to-end connection.
|
||||
|
||||
|
||||
|
||||
Security Analysis
|
||||
=================
|
||||
|
||||
Client fingerprinting or correlation may be possible based on requests.
|
||||
The client (originating) router may wish to randomize the "m" and "r" values instead of sending
|
||||
the same value to each hop; or send a limited set values that represent bandwidth "buckets",
|
||||
or some combination of both.
|
||||
|
||||
Over-allocation DDoS: While it may be possible to DDoS a router now by building and
|
||||
using a large number of tunnels through it, this proposal arguably makes it much easier,
|
||||
by simply requesting one or more tunnels with large bandwidth requests.
|
||||
|
||||
Implementations can and should use one or more of the following strategies
|
||||
to mitigate this risk:
|
||||
|
||||
- Overallocation of available bandwidth
|
||||
- Limit per-tunnel allocation to some percentage of available bandwidth
|
||||
- Limit rate of increase in allocated bandwidth
|
||||
- Limit rate of increase in used bandwidth
|
||||
- Limit allocated bandwidth for a tunnel if not used early in a tunnel's lifetime (use it or lose it)
|
||||
- Tracking average bandwidth per tunnel
|
||||
- Tracking requested vs. actual bandwidth used per tunnel
|
||||
|
||||
|
||||
Compatibility
|
||||
===============
|
||||
|
||||
No issues. All known implementations currently ignore the mapping field in build messages,
|
||||
and correctly skip over a non-empty options field.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Implementations may add support at any time, no coordination is needed.
|
||||
|
||||
As there is currently no API version defined where support for this proposal is required,
|
||||
routers should check for a "b" response to confirm support.
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [Tunnel-Creation-ECIES]
|
||||
{{ spec_url('tunnel-creation-ecies') }}
|
File diff suppressed because it is too large
Load Diff
@ -3,8 +3,8 @@ SSU Protocol Specification
|
||||
==========================
|
||||
.. meta::
|
||||
:category: Transports
|
||||
:lastupdated: 2024-01
|
||||
:accuratefor: 0.9.61
|
||||
:lastupdated: 2022-06
|
||||
:accuratefor: 0.9.54
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -12,10 +12,6 @@ SSU Protocol Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
DEPRECATED - SSU has been replaced by SSU2.
|
||||
SSU support was removed from i2pd in release 2.44.0 (API 0.9.56) 2022-11.
|
||||
SSU support was removed from Java I2P in release 2.4.0 (API 0.9.61) 2023-12.
|
||||
|
||||
See [SSU]_ for an overview of the SSU transport.
|
||||
|
||||
|
||||
|
@ -3,8 +3,8 @@ SSU2
|
||||
======
|
||||
.. meta::
|
||||
:category: Transports
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.65
|
||||
:lastupdated: 2023-01
|
||||
:accuratefor: 0.9.57
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -13,7 +13,7 @@ SSU2
|
||||
Status
|
||||
========
|
||||
|
||||
Substantially complete. See [Prop159]_ for additional background and goals,
|
||||
Testing in progress. See [Prop159]_ for additional background and goals,
|
||||
including security analysis, threat models, a review of SSU 1 security and issues,
|
||||
and excerpts of the QUIC specifications.
|
||||
|
||||
@ -40,7 +40,7 @@ Connection Migration 0.9.55+ dev 0.9.56 2022-11
|
||||
Immediate ACK flag 0.9.55+ dev 0.9.56 2022-11
|
||||
Key Rotation 0.9.57 2023-02 0.9.58 2023-05
|
||||
Disable SSU 1 (i2pd) 0.9.56 2022-11
|
||||
Disable SSU 1 (Java I2P) 0.9.58 2023-05 0.9.61 2023-12
|
||||
Disable SSU 1 (Java I2P) 0.9.58 2023-05 0.9.59 2023-08
|
||||
========================== ===================== ====================
|
||||
|
||||
Basic Session includes the handshake and data phase.
|
||||
@ -464,7 +464,7 @@ Before header encryption:
|
||||
Short Header
|
||||
`````````````
|
||||
The short header is 16 bytes. It is used for Session Created and for Data messages.
|
||||
Unauthenticated messages such as Session Request, Retry, and Peer Test will
|
||||
Uauthenticated messages such as Session Request, Retry, and Peer Test will
|
||||
always use the long header.
|
||||
|
||||
16 bytes is required, because
|
||||
@ -1075,7 +1075,7 @@ KDF for Session Request
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -1375,7 +1375,7 @@ KDF for Session Created and Session Confirmed part 1
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -1549,7 +1549,7 @@ Payload
|
||||
- DateTime block
|
||||
- Address block
|
||||
- Relay Tag block (optional)
|
||||
- New Token block (not recommended, see note)
|
||||
- New Token block (optional)
|
||||
- First Packet Number block (optional)
|
||||
- Options block (optional)
|
||||
- Termination block (not recommended, send in a retry message instead)
|
||||
@ -1589,10 +1589,6 @@ Notes
|
||||
|
||||
- Bob sends a relay tag block if requested by Alice in the Session Request.
|
||||
|
||||
- New Token block is not recommended in Session Created, because Bob
|
||||
should do validation of the Session Confirmed first. See
|
||||
the Tokens section below.
|
||||
|
||||
|
||||
Issues
|
||||
``````
|
||||
@ -1658,7 +1654,7 @@ This is the "se" message pattern:
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
k = keydata[32:64]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
@ -3864,12 +3860,9 @@ used as a keep-alive or to validate an IP/Port change.
|
||||
|
||||
Notes:
|
||||
|
||||
- A minimum data size of 8 bytes, containing random data,
|
||||
is recommended but not required.
|
||||
- The max size is not specified, but it should be well under
|
||||
1280, because the PMTU during the path validation phase is 1280.
|
||||
- Large challenge sizes are not recommended because they could
|
||||
be a vector for packet amplification attacks.
|
||||
A minimum data size of 8 bytes, containing random data,
|
||||
is recommended but not required.
|
||||
|
||||
|
||||
|
||||
Path Response
|
||||
@ -4223,9 +4216,7 @@ stores the values and associated IP and port (in-memory or persistently).
|
||||
The generator may not generate an opaque value, for example,
|
||||
using the SipHash (with a secret seed K0, K1) of the IP, port, and current hour or day,
|
||||
to create tokens that do not need to be saved in-memory,
|
||||
because this method makes it difficult to reject reused tokens and replay attacks.
|
||||
However, it is a topic for further study if we may migrate to such a scheme,
|
||||
as [WireGuard]_ does, using a 16-byte HMAC of a server secret and IP address.
|
||||
because this method make it difficult to reject reused tokens and replay attacks.
|
||||
|
||||
Tokens may only be used once.
|
||||
A token sent from Bob to Alice in a Retry message must be used immediately, and expires
|
||||
@ -4234,8 +4225,7 @@ A token sent in a New Token block in an established session
|
||||
may be used in a subsequent connection, and it
|
||||
expires at the time specified in that block.
|
||||
Expiration is specified by the sender; recommended values are
|
||||
several minutes minimum, one or more hours maximum, depending on
|
||||
desired maximum overhead of stored tokens.
|
||||
one hour minimum, several hours maximum.
|
||||
|
||||
If a router's IP or port changes, it must delete all saved tokens
|
||||
(both inbound and outbound) for the old IP or port, as they are no longer valid.
|
||||
@ -4246,15 +4236,9 @@ A router may choose to limit token storage, and remove the oldest stored tokens
|
||||
even if they have not expired.
|
||||
|
||||
New Token blocks may be sent from Alice to Bob or Bob to Alice.
|
||||
They would typically be sent at least once, during or soon after session establishment.
|
||||
Due to validation checks of the RouterInfo in the Session Confirmed message,
|
||||
Bob should not send a New Token block in the Session Created message,
|
||||
it may be sent with the ACK 0 and Router Info after the Session Confirmed is received
|
||||
and validated.
|
||||
|
||||
As session lifetimes are often longer than token expiration,
|
||||
the token should be resent before or after expiration with a new expiration time,
|
||||
or a new token should be sent.
|
||||
They would typically be sent once, during or soon after session establishment.
|
||||
The token may be resent before or after expiration with a new expiration time,
|
||||
or a new token may be sent.
|
||||
Routers should assume that only the last token received is valid;
|
||||
there is no requirement to store multiple inbound or outbound tokens for the same IP/port.
|
||||
|
||||
@ -4343,7 +4327,7 @@ An additional packet count limit may be useful as well to prevent
|
||||
buffer overflow in the kernel or in middleboxes, implementation dependent,
|
||||
although this may add significant complexity.
|
||||
If per-session and/or total packet output is bandwidth-limited and/or paced,
|
||||
this may mitigate the need for packet count limiting.
|
||||
this may mitigate the need for packet count ilmiting.
|
||||
|
||||
|
||||
|
||||
@ -4784,9 +4768,9 @@ Message Contents
|
||||
The Data messages should contain the following blocks.
|
||||
Order is not specified except that Padding must be last:
|
||||
|
||||
- Path Challenge or Path Response block.
|
||||
Path Challenge contains opaque data, recommended 8 bytes minimum.
|
||||
Path Response contains the data from the Path Challenge.
|
||||
- Path Validation or Path Response block.
|
||||
Path Validation contains opaque data, recommended 8 bytes minimum.
|
||||
Path Response contains the data from the Path Validation.
|
||||
- Address block containing the recipient's apparent IP
|
||||
- DateTime block
|
||||
- ACK block
|
||||
@ -4795,7 +4779,7 @@ Order is not specified except that Padding must be last:
|
||||
It is not recommended to include any other blocks
|
||||
(for example, I2NP) in the message.
|
||||
|
||||
It is allowed to include a Path Challenge block in the message
|
||||
It is allowed to include a Path Validation block in the message
|
||||
containing the Path Response, to initiate a validation
|
||||
in the other direction.
|
||||
|
||||
@ -4933,8 +4917,8 @@ the other peer should initiate a path challenge in the other direction.
|
||||
|
||||
Use as Ping/Pong
|
||||
-----------------
|
||||
Path Challenge and Path Response blocks may be used at any time as Ping/Pong packets.
|
||||
Reception of a Path Challenge block does not change any state at the receiver,
|
||||
Path Validation and Path Response blocks may be used at any time as Ping/Pong packets.
|
||||
Reception of a Path Validation block does not change any state at the receiver,
|
||||
unless received from a different IP/port.
|
||||
|
||||
|
||||
@ -5493,19 +5477,8 @@ are all in-session and are covered by the
|
||||
data phase ACK and retransmission processes.
|
||||
Relay Request, Relay Intro, and Relay Response blocks are ack-eliciting.
|
||||
|
||||
Note that usually, Charlie will respond immediately to a Relay Intro
|
||||
with a Relay Response, which should include an ACK block.
|
||||
In that case, no separate message with an ACK block is required.
|
||||
|
||||
Hole punch may be retransmitted, as in SSU 1.
|
||||
|
||||
Unlike I2NP messages, the Relay messages do not have unique identifiers,
|
||||
so duplicates must be detected by the relay state machine, using the nonce.
|
||||
Implementations may also need to maintain a cache of recently-used nonces,
|
||||
so that received duplicates may be detected even after the state machine for that nonce has completed.
|
||||
|
||||
|
||||
|
||||
IPv4/v6
|
||||
----------
|
||||
All features of SSU 1 relay are supported, including those documented in
|
||||
@ -6090,8 +6063,6 @@ Recommended Constants
|
||||
- Max ACK ranges: 256?
|
||||
- Max ACK depth: 512?
|
||||
- Padding distribution: 0-15 bytes, or greater
|
||||
- Data phase minimum retransmission timeout: 1 second, as in [RFC-6298]_
|
||||
- See also [RFC-6298]_ for additional guidance on retransmission timers for the data phase.
|
||||
|
||||
|
||||
Packet Overhead Analysis
|
||||
@ -6127,22 +6098,6 @@ Total 1314
|
||||
================== =========== ===== ====== ======= ====== =====
|
||||
|
||||
|
||||
Issues and Future Work
|
||||
======================
|
||||
|
||||
Tokens
|
||||
------
|
||||
|
||||
We specify above that the token must be a randomly-generated 8 byte value,
|
||||
not generate an opaque value such as a hash or HMAC of a server secret
|
||||
and the IP, port, due to reuse attacks.
|
||||
However, this requires temporary and (optionally) persistent storage of
|
||||
delivered tokens.
|
||||
[WireGuard]_ uses a 16-byte HMAC of a server secret and IP address,
|
||||
and the server secret rotates every two minutes.
|
||||
We should investigate something similar, with a longer server secret lifetime.
|
||||
If we embed a timestamp in the token, that may be a solution, but
|
||||
an 8-byte token may not be large enough for that.
|
||||
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user