From 0519ea476e9064198269f6544a355267f7c9af6f Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 27 Nov 2015 17:34:36 +0000 Subject: [PATCH] Add v3 datagram and raw to sink --- .../src/net/i2p/sam/client/SAMStreamSink.java | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java b/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java index aea68e5516..cf6d142f40 100644 --- a/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java +++ b/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java @@ -1,10 +1,13 @@ package net.i2p.sam.client; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.DatagramPacket; +import java.net.DatagramSocket; import java.net.Socket; import java.security.GeneralSecurityException; import java.util.HashMap; @@ -51,6 +54,7 @@ public class SAMStreamSink { " modes: stream: 0; datagram: 1; v1datagram: 2; raw: 3; v1raw: 4\n" + " -s: use SSL\n" + " multiple -o session options are allowed"; + private static final int V3DGPORT=9999; public static void main(String args[]) { Getopt g = new Getopt("SAM", args, "sb:m:p:u:v:w:"); @@ -176,6 +180,9 @@ public class SAMStreamSink { throw new IOException("2nd handshake failed"); if (_log.shouldLog(Log.DEBUG)) _log.debug("Handshake2 complete."); + } else if (_isV3 && (mode == DG || mode == RAW)) { + // set up a listening DatagramSocket + (new DGRcvr(mode)).start(); } writeDest(ourDest); } catch (IOException e) { @@ -183,6 +190,52 @@ public class SAMStreamSink { } } + private class DGRcvr extends I2PAppThread { + private final int _mode; + + public DGRcvr(int mode) { _mode = mode; } + + public void run() { + byte[] buf = new byte[32768]; + try { + Sink sink = new Sink("FAKE", "FAKEFROM"); + DatagramSocket dg = new DatagramSocket(V3DGPORT); + while (true) { + DatagramPacket p = new DatagramPacket(buf, 32768); + dg.receive(p); + int len = p.getLength(); + int off = p.getOffset(); + byte[] data = p.getData(); + _log.info("Got datagram length " + len); + if (_mode == DG) { + ByteArrayInputStream bais = new ByteArrayInputStream(data, off, len); + String line = DataHelper.readLine(bais); + if (line == null) { + _log.error("DGRcvr no header line"); + continue; + } + if (line.length() < 516) { + _log.error("DGRcvr line too short: \"" + line + '\n'); + continue; + } + String[] parts = line.split(" "); + String dest = parts[0]; + _log.info("DG is from " + dest); + for (int i = 1; i < parts.length; i++) { + _log.info("Parameter: " + parts[i]); + } + int left = bais.available(); + sink.received(data, off + len - left, left); + } else { + sink.received(data, off, len); + } + } + } catch (IOException ioe) { + _log.error("DGRcvr", ioe); + } + } + } + private static class Pinger extends I2PAppThread { private final OutputStream _out; @@ -471,10 +524,14 @@ public class SAMStreamSink { String style; if (mode == STREAM) style = "STREAM"; - else if (mode == DG || mode == V1DG) + else if (mode == V1DG) style = "DATAGRAM"; - else + else if (mode == DG) + style = "DATAGRAM PORT=" + V3DGPORT; + else if (mode == V1RAW) style = "RAW"; + else + style = "RAW PORT=" + V3DGPORT; String req = "SESSION CREATE STYLE=" + style + " DESTINATION=" + dest + ' ' + _conOptions + ' ' + sopts + '\n'; samOut.write(req.getBytes()); samOut.flush(); @@ -501,7 +558,7 @@ public class SAMStreamSink { } if (_log.shouldInfo()) _log.info(_destFile + " is located at " + destination); - if (mode != STREAM) { + if (mode == V1DG || mode == V1RAW) { // fake it so the sink starts eventHandler.streamConnectedReceived(destination, "FAKE"); } -- GitLab