package net.i2p.i2ptunnel.socks; import java.util.Map; import net.i2p.I2PAppContext; import net.i2p.data.Destination; import net.i2p.i2ptunnel.udp.*; import net.i2p.util.Log; /** * Strip a SOCKS header off a datagram, convert it to a Destination * Ref: RFC 1928 * * @author zzz */ public class SOCKSUDPUnwrapper implements Source, Sink { /** * @param cache put headers here to pass to SOCKSUDPWrapper */ public SOCKSUDPUnwrapper(Map<Destination, SOCKSHeader> cache) { this.cache = cache; } public void setSink(Sink sink) { this.sink = sink; } public void start() {} /** * * May throw RuntimeException from underlying sink * @throws RuntimeException */ public void send(Destination ignored_from, byte[] data) { SOCKSHeader h; try { h = new SOCKSHeader(data); } catch (IllegalArgumentException iae) { Log log = I2PAppContext.getGlobalContext().logManager().getLog(SOCKSUDPUnwrapper.class); log.error(iae.toString()); return; } Destination dest = h.getDestination(); if (dest == null) { // no, we aren't going to send non-i2p traffic to a UDP outproxy :) Log log = I2PAppContext.getGlobalContext().logManager().getLog(SOCKSUDPUnwrapper.class); log.error("Destination not found: " + h.getHost()); return; } cache.put(dest, h); int headerlen = h.getBytes().length; byte unwrapped[] = new byte[data.length - headerlen]; System.arraycopy(data, headerlen, unwrapped, 0, unwrapped.length); this.sink.send(dest, unwrapped); } private Sink sink; private Map<Destination, SOCKSHeader> cache; }