From 5adbf9050a471c02a44e1bae2dff57e6a22c79d9 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 27 Nov 2015 18:23:06 +0000 Subject: [PATCH] Forwarded raw datagrams will include a header line if HEADER=true Add support for raw with headers to sink client --- .../java/src/net/i2p/sam/SAMv3RawSession.java | 18 ++++++++++++- .../src/net/i2p/sam/client/SAMStreamSink.java | 26 ++++++++++++------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java b/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java index 658aaae0a4..b68f3a74a1 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java @@ -12,6 +12,7 @@ import java.util.Properties; import net.i2p.client.I2PSessionException; import net.i2p.data.DataFormatException; +import net.i2p.data.DataHelper; import net.i2p.util.Log; /** @@ -24,6 +25,7 @@ class SAMv3RawSession extends SAMRawSession implements SAMv3Handler.Session, SA private final SAMv3Handler handler; private final SAMv3DatagramServer server; private final SocketAddress clientAddress; + private final boolean _sendHeader; public String getNick() { return nick; } @@ -66,13 +68,27 @@ class SAMv3RawSession extends SAMRawSession implements SAMv3Handler.Session, SA } this.clientAddress = new InetSocketAddress(host, port); } + _sendHeader = ((handler.verMajor == 3 && handler.verMinor >= 2) || handler.verMajor > 3) && + Boolean.parseBoolean(props.getProperty("HEADER")); } public void receiveRawBytes(byte[] data, int proto, int fromPort, int toPort) throws IOException { if (this.clientAddress==null) { this.handler.receiveRawBytes(data, proto, fromPort, toPort); } else { - ByteBuffer msgBuf = ByteBuffer.allocate(data.length); + ByteBuffer msgBuf; + if (_sendHeader) { + StringBuilder buf = new StringBuilder(64); + buf.append("PROTOCOL=").append(proto) + .append(" FROM_PORT=").append(fromPort) + .append(" TO_PORT=").append(toPort) + .append('\n'); + String msg = buf.toString(); + msgBuf = ByteBuffer.allocate(msg.length()+data.length); + msgBuf.put(DataHelper.getASCII(msg)); + } else { + msgBuf = ByteBuffer.allocate(data.length); + } msgBuf.put(data); msgBuf.flip(); this.server.send(this.clientAddress, msgBuf); 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 cf6d142f40..05b79e1eeb 100644 --- a/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java +++ b/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java @@ -49,9 +49,9 @@ public class SAMStreamSink { private final Map<String, Sink> _remotePeers; private static I2PSSLSocketFactory _sslSocketFactory; - private static final int STREAM=0, DG=1, V1DG=2, RAW=3, V1RAW=4; + private static final int STREAM=0, DG=1, V1DG=2, RAW=3, V1RAW=4, RAWHDR = 5; private static final String USAGE = "Usage: SAMStreamSink [-s] [-m mode] [-v version] [-b samHost] [-p samPort] [-o opt=val] [-u user] [-w password] myDestFile sinkDir\n" + - " modes: stream: 0; datagram: 1; v1datagram: 2; raw: 3; v1raw: 4\n" + + " modes: stream: 0; datagram: 1; v1datagram: 2; raw: 3; v1raw: 4 raw-with-headers: 5\n" + " -s: use SSL\n" + " multiple -o session options are allowed"; private static final int V3DGPORT=9999; @@ -75,7 +75,7 @@ public class SAMStreamSink { case 'm': mode = Integer.parseInt(g.getOptarg()); - if (mode < 0 || mode > V1RAW) { + if (mode < 0 || mode > RAWHDR) { System.err.println(USAGE); return; } @@ -180,7 +180,7 @@ 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)) { + } else if (_isV3 && (mode == DG || mode == RAW || mode == RAWHDR)) { // set up a listening DatagramSocket (new DGRcvr(mode)).start(); } @@ -207,21 +207,25 @@ public class SAMStreamSink { int off = p.getOffset(); byte[] data = p.getData(); _log.info("Got datagram length " + len); - if (_mode == DG) { + if (_mode == DG || _mode == RAWHDR) { 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) { + if (_mode == DG && 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++) { + int i = 0; + if (_mode == DG) { + String dest = parts[0]; + _log.info("DG is from " + dest); + i++; + } + for ( ; i < parts.length; i++) { _log.info("Parameter: " + parts[i]); } int left = bais.available(); @@ -530,8 +534,10 @@ public class SAMStreamSink { style = "DATAGRAM PORT=" + V3DGPORT; else if (mode == V1RAW) style = "RAW"; - else + else if (mode == RAW) style = "RAW PORT=" + V3DGPORT; + else + style = "RAW HEADER=true PORT=" + V3DGPORT; String req = "SESSION CREATE STYLE=" + style + " DESTINATION=" + dest + ' ' + _conOptions + ' ' + sopts + '\n'; samOut.write(req.getBytes()); samOut.flush(); -- GitLab