Această pagină a fost actualizată ultima dată în Mai 2013 și deține informații clare pentru versiunea de router 0.9.6.

De ce scrie cod specific I2P?

Există mai multe modalități de utilizare a aplicațiilor în I2P. Folosind I2PTunnel, puteți utiliza aplicații obișnuite fără a fi necesar să programați suport I2P explicit. Acest lucru este foarte eficient pentru scenariul client-server, unde trebuie să vă conectați la un singur site web. Puteți crea pur și simplu un tunel folosind I2PTunnel pentru a vă conecta la acel site web, așa cum se arată în figura 1.

Dacă aplicația dvs. este distribuită, va necesita conexiuni la o mare cantitate de colegi. Folosind I2PTunnel, va trebui să creați un nou tunel pentru fiecare coleg pe care doriți să-l contactați, așa cum se arată în figura 2. Desigur, acest proces poate fi automatizat, dar rularea multor instanțe I2PTunnel creează o cantitate mare de cheltuieli generale. În plus, cu multe protocoale va trebui să-i forțezi pe toți utilizați același set de porturi pentru toți colegii - de ex. dacă doriți să rulați în mod sigur DCC chat, toată lumea trebuie să fie de acord că portul 10001 este Alice, portul 10002 este Bob, port 10003 este Charlie și așa mai departe, deoarece protocolul include informații specifice TCP / IP (gazdă și port).

Aplicațiile generale de rețea trimit adesea o mulțime de date suplimentare care ar putea fi utilizate pentru identificarea utilizatorilor. Numele de gazdă, numerele de port, zonele de timp, seturile de caractere etc. sunt adesea trimise fără a informa utilizatorul. Ca atare, proiectarea protocolului de rețea în special cu anonimatul poate evita compromiterea identităților utilizatorului.

Există, de asemenea, considerente de eficiență de revizuit la stabilirea modului de a interacționa pe partea de sus a I2P. Biblioteca de streaming și lucrurile construite deasupra ei funcționează cu strângeri de mână similare cu TCP, în timp ce protocoalele I2P de bază (I2NP și I2CP) se bazează strict pe mesaje (cum ar fi UDP sau în unele cazuri IP brut). Importanta distincția este că, cu I2P, comunicarea funcționează pe o rețea lungă de grăsimi - fiecare mesaj de la capăt la sfârșit va avea latențe nontriviale, dar poate conține sarcini utile de până la mai multe KB. O aplicație care are nevoie de o cerere simplă și răspuns poate scăpa de orice stare și scade latența provocată de apăsările de mână de pornire și de apăsare folosind (cel mai bun efort) dateagrame fără a fi nevoie să vă faceți griji cu privire la detectarea MTU sau fragmentarea mesajelor.

Crearea unei conexiuni server-client folosind I2PTunnel necesită doar crearea unui singur tunel.

Figura 1: Crearea unei conexiuni server-client folosind I2PTunnel necesită doar crearea unui singur tunel.

Configurarea conexiunilor pentru aplicații peer-to-peer necesită o cantitate foarte mare de tuneluri.

Figura 2: Configurarea conexiunilor pentru aplicații peer-to-peer necesită o cantitate foarte mare de tuneluri.

În rezumat, mai multe motive pentru a scrie cod specific I2P:
  • Crearea unei cantități mari de instanțe I2PTunnel consumă o cantitate non-banală de resurse, ceea ce este problematic pentru aplicațiile distribuite (este necesar un nou tunel pentru fiecare coleg).
  • Protocoalele generale de rețea trimit adesea o mulțime de date suplimentare care pot fi utilizate pentru identificarea utilizatorilor. Programarea specifică pentru I2P permite crearea unui protocol de rețea care nu scurge astfel de informații, păstrând utilizatorii anonimi și siguri.
  • Protocoalele de rețea concepute pentru utilizare pe internetul obișnuit pot fi ineficiente pe I2P, care este o rețea cu o latență mult mai mare.

I2P acceptă o interfață standard de pluginuri pentru dezvoltatori astfel încât aplicațiile să poată fi ușor integrate și distribuite.

Aplicații scrise în Java și accesibile / rulabile folosind o interfață HTML prin intermediul webapps / app.war standard poate fi considerat pentru includerea în distribuția i2p.

Concepte importante

Există câteva modificări care necesită ajustarea la utilizarea I2P:

Destinație ~ = gazdă + port

O aplicație care rulează pe I2P trimite mesaje de la și primește mesaje către un punct final unic sigur criptografic - o „destinație”. În TCP sau UDP termeni, o destinație ar putea fi (în mare parte) considerată echivalentul unui nume de gazdă plus pereche de numere de port, deși există câteva diferențe.

  • O destinație I2P în sine este o construcție criptografică - toate datele trimise către unul este criptat ca și cum ar exista o implementare universală a IPsec cu (anonimizat) locația punctului final semnat ca și cum ar exista o implementare universală a DNSSEC.
  • Destinațiile I2P sunt identificatori mobile - pot fi mutați de la un router I2P la un altul (sau poate chiar „multihome” - funcționează pe mai multe routere la o singura data). Acest lucru este cu totul diferit de lumea TCP sau UDP unde un singur punct final (port) trebuie să stea pe o singură gazdă.
  • Destinațiile I2P sunt urâte și mari - în spatele scenei, conțin un ElGamal de 2048 biți cheia publică pentru criptare, o cheie publică de 1024 biți DSA pentru semnare și o dimensiune variabilă certificat, care poate conține date de lucru sau date orbit.

    Există modalități existente de a face referire la aceste destinații mari și urâte pe scurt și nume frumoase (de exemplu, "irc.duck.i2p"), dar acele tehnici nu garantează unicitate globală (din moment ce sunt stocate local într-o bază de date de pe aparatul fiecărei persoane) iar mecanismul actual nu este deosebit de scalabil și nici sigur (actualizările la lista gazdă sunt gestionat folosind „abonamente” la servicii de denumire). Pot exista unele sigure, care pot fi citite de oameni, scalabile și la nivel global unic, un sistem de denumire într-o zi, dar aplicațiile nu ar trebui să depindă de faptul că acesta este în loc, de vreme ce există cei care nu cred că o astfel de fiară este posibilă. Mai multe informații despre sistemul de denumire sunt disponibile.

Deși majoritatea aplicațiilor nu trebuie să distingă protocoale și porturi, I2P le acceptă. Aplicațiile complexe pot specifica un protocol, de la port și la port, pe bază de mesaj, la trafic multiplex activat o singură destinație. Consultați pagina de date pentru detalii. Aplicațiile simple funcționează ascultând „toate protocoalele” de pe „toate porturile” unei destinații.

Anonimatul și confidențialitatea

I2P are criptare transparentă de la capăt la capăt și autentificare pentru toate datele transmise prin rețea - dacă Bob trimite la destinația lui Alice, doar destinația lui Alice o poate primi și dacă Bob folosește datagrame sau streaming biblioteca, Alice stie sigur ca destinatia lui Bob este cea care a trimis datele.

Desigur, I2P anonimizează transparent date trimise între Alice și Bob, dar nu face nimic pentru a anonimiza conținutul a ceea ce ei trimite. De exemplu, dacă Alice trimite lui Bob un formular cu numele ei complet, ID-urile guvernului și numere de carduri de credit, nu se poate face nimic I2P. Ca atare, protocoalele și aplicațiile ar trebui rețineți ce informații încearcă să protejeze și ce informații sunt dispuse a expune.

Diagramele de date I2P pot fi de până la mai multe KB

Applications that use I2P datagrams (either raw or repliable ones) can essentially be thought of in terms of UDP - the datagrams are unordered, best effort, and connectionless - but unlike UDP, applications don't need to worry about MTU detection and can simply fire off large datagrams. While the upper limit is nominally 32 KB, the message is fragmented for transport, thus dropping the reliability of the whole. Datagrams over about 10 KB are not currently recommended. See the datagram page for details. For many applications, 10 KB of data is sufficient for an entire request or response, allowing them to transparently operate in I2P as a UDP-like application without having to write fragmentation, resends, etc.

Opțiuni de dezvoltare

Există mai multe mijloace de a trimite date peste I2P, fiecare cu propriile pro și contra. Streaming lib este interfața recomandată, utilizată de majoritatea aplicațiilor I2P.

Streaming Lib

Biblioteca completă de streaming este acum interfață standard . Permite programarea folosind socluri asemănătoare TCP, așa cum este explicat în ghidul de dezvoltare Streaming.

BOB

BOB is the Basic Open Bridge, allowing an application in any language to make streaming connections to and from I2P. At this point in time it lacks UDP support, but UDP support is planned in the near future. BOB also contains several tools, such as destination key generation, and verification that an address conforms to I2P specifications. Up to date info and applications that use BOB can be found at this eepsite.

SAM, SAM V2, SAM V3

SAM nu este recomandat. SAM V2 este în regulă, SAM V3 este recomandat.

SAM is the Simple Anonymous Messaging protocol, allowing an application written in any language to talk to a SAM bridge through a plain TCP socket and have that bridge multiplex all of its I2P traffic, transparently coordinating the encryption/decryption and event based handling. SAM supports three styles of operation:

  • fluxuri, pentru când Alice și Bob vor să își transmită date reciproc în mod fiabil și în ordine
  • dateagrame repliable, pentru când Alice vrea să-i trimită lui Bob un mesaj căruia îi poate răspunde Bob
  • dateagrame brute, când Alice vrea să reducă cea mai mare lățime de bandă și performanță posibilă, și lui Bob nu îi pasă dacă expeditorul datelor este autentificat sau nu (de exemplu, datele transferate se autentifică de la sine)

SAM V3 vizează același obiectiv ca SAM și SAM V2, dar nu necesită multiplexare/demultiplexare. Fiecare flux I2P este gestionat de propria priză între aplicație și podul SAM. În plus, datagramele pot fi trimise și primite de către aplicație prin intermediul datagramei comunicații cu podul SAM.

SAM V2 este o versiune nouă folosită de imule care rezolvă unele dintre problemele din SAM.
SAM V3 este utilizat de imule începând cu versiunea 1.4.0.

I2PTunnel

The I2PTunnel application allows applications to build specific TCP-like tunnels to peers by creating either I2PTunnel 'client' applications (which listen on a specific port and connect to a specific I2P destination whenever a socket to that port is opened) or I2PTunnel 'server' applications (which listen to a specific I2P destination and whenever it gets a new I2P connection it outproxies to a specific TCP host/port). These streams are 8-bit clean, and are authenticated and secured through the same streaming library that SAM uses, but there is a nontrivial overhead involved with creating multiple unique I2PTunnel instances, since each have their own unique I2P destination and their own set of tunnels, keys, etc.

SOCKS

I2P acceptă un proxy SOCKS V4 și V5. Conexiunile de ieșire funcționează bine. Funcțiile de intrare (server) și UDP pot fi incomplete și ne testate.

Ministreaming

Șters

Există o simplă bibliotecă „ministreaming”, dar acum ministreaming.jar conține doar interfețele pentru biblioteca completă de streaming.

Datagrame

Recomandat pentru aplicații de tip UDP

Biblioteca Datagram permite trimiterea de pachete asemănătoare cu UDP. Este posibil să utilizați:

  • Datagrame replicabile
  • Datagramele brute

I2CP

Nu se recomandă

I2CP itself is a language independent protocol, but to implement an I2CP library in something other than Java there is a significant amount of code to be written (encryption routines, object marshalling, asynchronous message handling, etc). While someone could write an I2CP library in C or something else, it would most likely be more useful to use the C SAM library instead.

Aplicații Web

I2P vine cu serverul Web Jetty, iar configurarea pentru a utiliza serverul Apache în schimb este simplă. Orice tehnologie standard de aplicații web ar trebui să funcționeze.

Începeți să dezvoltați - un ghid simplu

Dezvoltarea folosind I2P necesită o instalare I2P funcțională și un mediu de dezvoltare la alegere. Dacă utilizați Java, puteți începe dezvoltarea cu biblioteca de streaming sau cu biblioteca de date. Folosind un alt limbaj de programare, SAM sau BOB pot fi utilizate.

Dezvoltarea cu biblioteca de streaming

Următorul exemplu arată cum puteți crea aplicații client și server similare TCP folosind biblioteca de streaming.

Aceasta va necesita următoarele biblioteci din calea de clasă:

  • $I2P/lib/streaming.jar: Însuși biblioteca de streaming
  • $I2P/lib/mstreaming.jar: Fabrică și interfețe pentru biblioteca de streaming
  • $I2P/lib/i2p.jar: Clasele I2P standard, structuri de date, API și utilități

Puteți prelua acestea dintr-o instalație I2P sau puteți adăuga următoarele dependențe din Maven Central:

  • net.i2p:i2p:0.9.44
  • net.i2p.client:streaming:0.9.44

Comunicarea în rețea necesită utilizarea soclurilor de rețea I2P. Pentru a demonstra acest lucru, vom crea o aplicație în care un client poate trimite mesaje text către un server, cine va tipări mesajele și le va trimite înapoi clientului. Cu alte cuvinte, serverul va funcționa ca un ecou.

We will start by initializing the server application. This requires getting an I2PSocketManager and creating an I2PServerSocket. We will not provide the I2PSocketManagerFactory with the saved keys for an existing Destination, so it will create a new Destination for us. So we will ask the I2PSocketManager for an I2PSession, so we can find out the Destination that was created, as we will need to copy and paste that information later so the client can connect to us.

package i2p.echoserver;

import net.i2p.client.I2PSession;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;

public class Main {

    public static void main(String[] args) {
        //Initialize application
        I2PSocketManager manager = I2PSocketManagerFactory.createManager();
        I2PServerSocket serverSocket = manager.getServerSocket();
        I2PSession session = manager.getSession();
        //Print the base64 string, the regular string would look like garbage.
        System.out.println(session.getMyDestination().toBase64());
        //The additional main method code comes here...
    }

}

Exemplu de cod 1: inițializarea aplicației server.

Once we have an I2PServerSocket, we can create I2PSocket instances to accept connections from clients. In this example, we will create a single I2PSocket instance, that can only handle one client at a time. A real server would have to be able to handle multiple clients. To do this, multiple I2PSocket instances would have to be created, each in separate threads. Once we have created the I2PSocket instance, we read data, print it and send it back to the client. The bold code is the new code we add.

package i2p.echoserver;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.util.I2PThread;

import net.i2p.client.I2PSession;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;

public class Main {

    public static void main(String[] args) {
        I2PSocketManager manager = I2PSocketManagerFactory.createManager();
        I2PServerSocket serverSocket = manager.getServerSocket();
        I2PSession session = manager.getSession();
        //Print the base64 string, the regular string would look like garbage.
        System.out.println(session.getMyDestination().toBase64());

        //Create socket to handle clients
        I2PThread t = new I2PThread(new ClientHandler(serverSocket));
        t.setName("clienthandler1");
        t.setDaemon(false);
        t.start();
    }

    private static class ClientHandler implements Runnable {

        public ClientHandler(I2PServerSocket socket) {
            this.socket = socket;
        }

        public void run() {
            while(true) {
                try {
                    I2PSocket sock = this.socket.accept();
                    if(sock != null) {
                        //Receive from clients
                        BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                        //Send to clients
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
                        String line = br.readLine();
                        if(line != null) {
                            System.out.println("Received from client: " + line);
                            bw.write(line);
                            bw.flush(); //Flush to make sure everything got sent
                        }
                        sock.close();
                    }
                } catch (I2PException ex) {
                    System.out.println("General I2P exception!");
                } catch (ConnectException ex) {
                    System.out.println("Error connecting!");
                } catch (SocketTimeoutException ex) {
                    System.out.println("Timeout!");
                } catch (IOException ex) {
                    System.out.println("General read/write-exception!");
                }
            }
        }

        private I2PServerSocket socket;

    }

}

Exemplu de cod 2: acceptarea conexiunilor de la clienți și gestionarea mesajelor.

Când executați codul serverului de mai sus, ar trebui să imprime ceva de genul acesta (dar fără terminații de linie, ar trebui să fie pur și simplu un bloc imens de caractere):

    y17s~L3H9q5xuIyyynyWahAuj6Jeg5VC~Klu9YPquQvD4vlgzmxn4yy~5Z0zVvKJiS2Lk
    poPIcB3r9EbFYkz1mzzE3RYY~XFyPTaFQY8omDv49nltI2VCQ5cx7gAt~y4LdWqkyk3au
    6HdfYSLr45zxzWRGZnTXQay9HPuYcHysZHJP1lY28QsPz36DHr6IZ0vwMENQsnQ5rhq20
    jkB3iheYJeuO7MpL~1xrjgKzteirkCNHvXN8PjxNmxe-pj3QgOiow-R9rEYKyPAyGd2pe
    qMD-J12CGfB6MlnmH5qPHGdZ13bUuebHiyZ1jqSprWL-SVIPcynAxD2Uu85ynxnx31Fth
    nxFMk07vvggBrLM2Sw82pxNjKDbtO8reawe3cyksIXBBkuobOZdyOxp3NT~x6aLOxwkEq
    BOF6kbxV7NPRPnivbNekd1E1GUq08ltDPVMO1pKJuGMsFyZC4Q~osZ8nI59ryouXgn97Q
    5ZDEO8-Iazx50~yUQTRgLMOTC5hqnAAAA
    
Aceasta este reprezentarea de bază 64 a Destinației serverului. Clientul va avea nevoie de acest șir pentru a ajunge la server.

Now, we will create the client application. Again, a number of steps are required for initialization. Again, we will need to start by getting an I2PSocketManager. We won't use an I2PSession and an I2PServerSocket this time. Instead, we will use the server Destination string to start our connection. We will ask the user for the Destination string, and create an I2PSocket using this string. Once we have an I2PSocket, we can start sending and receiving data to and from the server.

package i2p.echoclient;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;

public class Main {

    public static void main(String[] args) {
        I2PSocketManager manager = I2PSocketManagerFactory.createManager();
        System.out.println("Please enter a Destination:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String destinationString;
        try {
            destinationString = br.readLine();
        } catch (IOException ex) {
            System.out.println("Failed to get a Destination string.");
            return;
        }
        Destination destination;
        try {
            destination = new Destination(destinationString);
        } catch (DataFormatException ex) {
            System.out.println("Destination string incorrectly formatted.");
            return;
        }
        I2PSocket socket;
        try {
            socket = manager.connect(destination);
        } catch (I2PException ex) {
            System.out.println("General I2P exception occurred!");
            return;
        } catch (ConnectException ex) {
            System.out.println("Failed to connect!");
            return;
        } catch (NoRouteToHostException ex) {
            System.out.println("Couldn't find host!");
            return;
        } catch (InterruptedIOException ex) {
            System.out.println("Sending/receiving was interrupted!");
            return;
        }
        try {
            //Write to server
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("Hello I2P!\n");
            //Flush to make sure everything got sent
            bw.flush();
            //Read from server
            BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String s = null;
            while ((s = br2.readLine()) != null) {
                System.out.println("Received from server: " + s);
            }
            socket.close();
        } catch (IOException ex) {
            System.out.println("Error occurred while sending/receiving!");
        }
    }

}

Exemplu de cod 3: pornirea clientului și conectarea acestuia la aplicația serverului.

Finally, you can run both the server and the client application. First, start the server application. It will print a Destination string (like shown above). Next, start the client application. When it requests a Destination string, you can enter the string printed by the server. The client will then send 'Hello I2P!' (along with a newline) to the server, who will print the message and send it back to the client.

Felicitări, ați comunicat cu succes peste I2P!

Aplicații existente

Contactați-ne dacă doriți să contribuiți.

See also all the plugins on plugins.i2p, the applications and source code listed on echelon.i2p, and the application code hosted on git.repo.i2p.

See also the bundled applications in the I2P distribution - SusiMail and I2PSnark.

Idei de aplicare

  • Server NNTP - au existat unele în trecut, niciuna în acest moment
  • Server Jabber - au existat unele în trecut și există unul în acest moment, cu acces la internetul public
  • Server și proxy cheie PGP
  • Aplicații de distribuție a conținutului / DHT - reînvierea spațiului de alimentare, port dijjer, căutați alternative
  • Ajutați-vă cu dezvoltarea Syndie
  • Aplicații bazate pe web - Cerul este limita pentru găzduirea bazată pe servere web aplicații precum bloguri, paste, stocare, urmărire, fluxuri etc. Orice tehnologie web sau CGI, precum Perl, PHP, Python sau Ruby vor funcționa.
  • Resureați câteva aplicații vechi, mai multe anterior în pachetul sursă i2p - bogobot, pantaloni, proxysript, q, stasher, proxy șosete, i2ping, feedspace